Почему и когда использовать статические структуры в C-программировании?
Я часто видел объявления статической структуры в коде драйвера, который меня попросили изменить.
Я пытался найти информацию о том, почему structs
объявляются статичными и мотивация для этого.
Может кто-нибудь из вас, пожалуйста, помогите мне понять это?
5 ответов
static
Ключевое слово в C имеет несколько эффектов, в зависимости от контекста, к которому оно применяется.
- при применении к переменной, объявленной внутри функции, значение этой переменной будет сохраняться между вызовами функции.
- при применении к переменной, объявленной вне функции, или к функции, видимость этой переменной или функции ограничивается "единицей перевода", в которой она объявлена, то есть самим файлом. Для переменных это сводится к виду "локально видимой глобальной переменной".
Оба использования довольно распространены в относительно низкоуровневом коде, таком как драйверы.
Первый и последний, когда применяются к переменным, позволяют функциям сохранять понятие состояния между вызовами, что может быть очень полезно, но это может также вызвать всевозможные неприятные проблемы, когда код используется в любом контексте, где он используется одновременно, либо несколькими потоками, либо несколькими вызывающими. Если вы не можете гарантировать, что код будет строго вызываться последовательно одним "пользователем", вы можете передать своего рода "контекстную" структуру, которая поддерживается вызывающей стороной при каждом вызове.
Последнее, примененное к функциям, позволяет программисту сделать функцию невидимой извне модуля, и МОЖЕТ быть несколько быстрее с некоторыми компиляторами для определенных архитектур, потому что компилятор знает, что он не должен делать переменную / функцию доступной извне модуль - позволяющий встроить функцию, например.
Что-то, что, очевидно, все остальные ответы, кажется, пропускают static
is и указывает также продолжительность хранения объекта, а также автоматическое (локальные переменные) и выделенное (память, возвращаемая malloc и friends).
Объекты со статической продолжительностью хранения инициализируются до запуска main(), либо с указанным инициализатором, либо, если он не был задан, как если бы ему был присвоен 0 (для структур и массивов это выполняется для каждого члена и рекурсивно).
Второе свойство static
наборы для идентификатора, это его связь, которая является концепцией, используемой во время соединения, и сообщает компоновщику, какие идентификаторы ссылаются на один и тот же объект. static
Ключевое слово дает идентификатору внутреннюю связь, что означает, что он не может ссылаться на идентификаторы с тем же именем в другой единице перевода.
И чтобы быть педантичным ко всем небрежным ответам, которые я читал ранее: на статическую переменную нельзя ссылаться нигде в объявленном файле. Его область действия - только от объявления (которое может быть между определениями функций) до конца исходного файла - или даже меньше, до конца окружающего блока.
переменная структуры
Для структурной переменной типа static struct S s;
Это широко обсуждалось на: Что означает "статический"?
определение структуры: нет эффекта:
static struct S { int i; int j; };
это точно так же, как:
struct S { int i; int j; };
так что никогда не используйте его. GCC 4.8 выдает предупреждение, если делает это.
Это связано с тем, что определения структуры не имеют хранения и не генерируют символы в объектных файлах, таких как переменные и функции. Просто попробуйте скомпилировать и декомпилировать:
struct S { int i; int j; };
int i;
с:
gcc -c main.c
nm main.o
и вы увидите, что нет S
символ, но есть i
условное обозначение.
Компилятор просто использует определения для вычисления смещения полей во время компиляции.
Поэтому они должны быть включены в заголовочные файлы.
То же самое касается enum
,
Определение структуры C++: устарело в C++11
Проект стандарта C++11 N3337 Приложение C 7.1.1:
Изменение: в C++ статические или внешние указатели могут применяться только к именам объектов или функций. Использование этих описателей с объявлениями типов недопустимо в C++. В Си эти спецификаторы игнорируются при использовании в объявлениях типов.
Смотрите также: /questions/18897295/kak-vyi-sozdaete-staticheskij-klass-v-c/18897318#18897318
Если вы объявите переменную как static
, он виден только в этой единице перевода (если объявлен глобально) или сохраняет свое значение от вызова к вызову (если объявлен внутри функции).
В вашем случае, я думаю, это первый случай. В этом случае, вероятно, программист не хотел, чтобы структура была видна из других файлов.
static
модификатор для struct
ограничивает область видимости структуры текущим переводчиком (т. е. файлом).
ПРИМЕЧАНИЕ. В этом ответе предполагается (как указали другие респонденты), что ваше объявление не входит в функцию.