Причины использовать статические функции и переменные в C - PullRequest
25 голосов
/ 04 июня 2010

Интересно, как использовать ключевое слово static в качестве ограничения области действия для переменных в файле в C.

Стандартный способ построить программу на C, как я вижу, это:

  • имеет кучу файлов c, определяющих функции и переменные, возможно область действия ограничена static.
  • имеет кучу h файлов, объявляющих функции и, возможно, переменные соответствующего c-файла, для использования другими c-файлами. Частные функции и переменные не публикуются в файле h.
  • каждый файл c компилируется отдельно в файл o.
  • все файлы o связаны вместе с файлом приложения.

Я вижу две причины объявить глобал как static, если переменная все равно не опубликована в файле h:

  • один для удобства чтения. Сообщите будущим читателям, включая меня, что к переменной нет доступа ни в каком другом файле.
  • Во-вторых, нужно запретить повторному указанию переменной c-файла как extern. Я предполагаю, что компоновщик не хотел бы, чтобы переменная была extern и static. (Мне не нравится идея файла, повторно обозначающего переменную, принадлежащую кому-то другому, как extern, это нормально?)

Любая другая причина?

То же самое относится к static функциям. Если прототип не опубликован в файле h, другие файлы могут вообще не использовать эту функцию, так зачем вообще ее определять static? Я вижу те же две причины, но не более.

Ответы [ 6 ]

26 голосов
/ 04 июня 2010

Когда вы говорите об информировании других читателей, рассматривайте сам компилятор как читателя. Если переменная объявлена ​​static, это может повлиять на степень оптимизации.

Переопределить переменную static как extern невозможно, но компилятор (как обычно) даст вам достаточно веревки, чтобы повеситься.

Если я напишу static int foo; в одном файле и int foo; в другом, они считаются разными переменными , несмотря на то, что имеют одинаковые имя и тип - компилятор не будет жаловаться, но вы, вероятно, получите очень позже запутался, пытаясь прочитать и / или отладить код. (Если я напишу extern int foo; во втором случае, ссылка не будет установлена, если я не объявлю нестатический int foo; где-то еще.)

Глобальные переменные редко появляются в заголовочных файлах, но когда они это делают, они должны быть объявлены extern. В противном случае, в зависимости от вашего компилятора, вы рискуете, что каждый исходный файл, который включает этот заголовок, объявит свою собственную копию переменной: в лучшем случае это вызовет сбой ссылки (символ с множественными определениями) и в худшем случае несколько запутанных случаев затенения.

9 голосов
/ 04 июня 2010

Объявляя переменную static на уровне файла (static внутри функции имеет другое значение), вы запрещаете другим единицам доступ к ней, например, если вы попытаетесь использовать переменную внутри другого модуля (объявленного с extern), компоновщик не найдет этот символ.

8 голосов
/ 04 июня 2010

Когда вы объявляете статическую функцию, вызов функции является «ближним вызовом», и теоретически он работает лучше, чем «дальний вызов». Вы можете Google для получения дополнительной информации. Это - это то, что я нашел с помощью простого поиска в Google.

1 голос
/ 01 апреля 2014

Если вы объявляете переменную foo в файле ac, не делая ее статичной, и переменную foo в файле bc, не делая ее статичной, оба автоматически становятся внешними, что означает, что компоновщик может пожаловаться, если вы инициализируете оба, и назначите одну и ту же область памяти если не жалуется. Ожидайте веселой отладки вашего кода.

Если вы пишете функцию foo () в файле ac, не делая ее статичной, и функцию foo () в файле bc, не делая ее статичной, компоновщик может жаловаться, но если этого не происходит, все вызовы foo ( ) будет вызывать ту же функцию. Ожидайте веселой отладки вашего кода.

1 голос
/ 04 июня 2010

Если глобальная переменная объявлена ​​статической, компилятор может иногда оптимизировать результаты лучше, чем если бы это было не так. Поскольку компилятор знает, что переменная не может быть доступна из других исходных файлов, он может сделать более точные выводы о том, что делает ваш код (например, «эта функция не изменяет эту переменную»), что иногда может привести к более быстрой генерации кода. Очень немногие компиляторы / компоновщики могут выполнять такие виды оптимизации для разных единиц перевода.

0 голосов
/ 04 июня 2010

Мое любимое использование статики - возможность хранить методы, которые мне не нужны, для инъекции или создания объекта для использования, как я вижу, частные статические методы всегда полезны, где для публичной статики вы должны поместить еще несколько время подумать о том, что вы делаете, чтобы избежать того, что определено как сумасшедший, получить себе слишком много веревки и случайно повесить себя!

Мне нравится хранить папку для классов Helper для большинства моих проектов, которые в основном состоят из статических методов, позволяющих выполнять задачи быстро и эффективно на лету, без необходимости каких-либо объектов!

...