Почему и когда использовать статические структуры в программировании на С?

Я часто видел объявления статической структуры в коде драйвера, к которому меня попросили изменить.

Я попытался найти информацию о том, почему structs объявлены статическими и мотивацией для этого.

Может кто-нибудь из вас, пожалуйста, помогите мне понять это?

+32
источник поделиться
5 ответов

Ключевое слово static в C имеет несколько эффектов, в зависимости от контекста, к которому он применяется.

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

Оба использования довольно распространены в относительно низкоуровневом коде, таком как драйверы.

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

Последний, применяемый к функциям, позволяет программисту сделать функцию невидимой из-за пределов модуля, и она MAY будет несколько быстрее с некоторыми компиляторами для некоторых архитектур, потому что компилятор знает, что это не " t должен сделать переменную/функцию доступной вне модуля, что позволяет использовать функцию, например, внутри.

+28
источник

Что-то, что, по-видимому, все другие ответы, кажется, не хватает: static is и указывает также продолжительность хранения для объекта, а также автоматическая (локальные переменные) и выделено (память возвращается malloc и друзьями).

Объекты со статической продолжительностью хранения инициализируются до начала main(), либо с указанным инициализатором, либо, если ни один не указан, как если бы ему было присвоено 0 (для структур и массивов это относится к каждому члену и рекурсивно).

Второе свойство static устанавливает для идентификатора, является его linkage, которое является понятием, используемым во время связи, и сообщает компоновщику, какие идентификаторы относятся к одному и тому же объекту. Ключевое слово static делает идентификатор внутренней связью, что означает, что он не может ссылаться на идентификаторы с тем же именем в другой единицы перевода.

И чтобы быть педантичным обо всех небрежных ответах, которые я читал раньше: статическая переменная не может быть указана нигде в объявленном файле. Его область действия - только от ее объявления (которое может быть между определениями функций) до конца исходного файла - или даже меньше - до конца закрывающего блока.

+26
источник

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

В вашем случае я предполагаю, что это первый случай. В этом случае, вероятно, программист не хотел, чтобы структура была видна из других файлов.

+8
источник

переменная структуры

Для структурной переменной, такой как static struct S s; это широко обсуждалось на: Что означает "статический" в C?

определение структуры: нет эффекта:

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:

Изменение: в С++ статические или внешние указатели могут применяться только к именам объектов или функций. Использование этих описателей с объявлениями типов недопустимо в С++. В Си эти спецификаторы игнорируются при использовании в объявлениях типов.

Смотрите также: fooobar.com/questions/32808/...

+8
источник

Модификатор static для struct ограничивает область видимости структуры текущей единицей перевода (т.е. файл).

ПРИМЕЧАНИЕ. Этот ответ предполагает (как указывали другие респонденты), что ваша декларация не входит в функцию.

+7
источник

Посмотрите другие вопросы по меткам или Задайте вопрос