Глобальные переменные в C статичны или нет?

Являются ли глобальные переменные в C static или extern по умолчанию?
Если глобальные переменные по умолчанию static, это означает, что мы сможем получить к ним доступ в одном файле, но мы также можем использовать глобальные переменные в разных файлах. < br> Означает ли это, что по умолчанию у них extern хранилище?


person Mishthi    schedule 21.11.2010    source источник


Ответы (3)


Если вы не укажете класс хранения (то есть ключевые слова extern или static), то по умолчанию глобальные переменные имеют внешнюю связь. Из стандарта C99:

§6.2.2 Связывание идентификаторов

3) Если объявление идентификатора области файла для объекта или функции содержит спецификатор класса хранения static, идентификатор имеет внутреннюю связь.

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

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

person Adam Rosenfield    schedule 21.11.2010
comment
также актуально: раздел 6.9.2, в котором описаны предварительные определения; §4 этого раздела явно показывает, как взаимодействуют несколько определений переменных области видимости файла. - person Christoph; 21.11.2010
comment
@Mishthi: Вы имеете в виду статическую и внешнюю переменную? Боюсь, это невозможно. - person Saurabh Manchanda; 21.11.2010
comment
@Mishthi: static extern varx - неопределенное поведение. Переменная не может быть одновременно static и extern, она должна быть одной или другой. - person Adam Rosenfield; 21.11.2010
comment
Верно ли это и в C ++? Или просто C? - person SSH This; 14.04.2012
comment
@SSHThis: Да, то же самое и в C ++. См. C ++ 03 §3.5 [basic.link]. - person Adam Rosenfield; 15.04.2012
comment
На самом деле static extern varx; не является неопределенным поведением; это нарушение ограничения. C11 §6.7.1 Классы хранения ¶2: < i> В спецификаторах объявления в объявлении может быть указан не более одного спецификатора класса хранения, за исключением того, что _Thread_local может появляться с static или extern.. Также существует проблема с типом 'implicit int' в попытке объявления - это не было законным в стандарте C в текущем тысячелетии (это было запрещено C99, хотя некоторые компиляторы все еще разрешают это, если не будут отклонены). - person Jonathan Leffler; 17.05.2019

В C глобальная переменная, не имеющая инициализатора или каких-либо спецификаторов класса хранения, является предварительным определением переменной со статической продолжительностью хранения и внешней связью.

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

person CB Bailey    schedule 21.11.2010

Глобальные переменные в C по умолчанию являются внешними .. (т.е. они имеют внешнюю связь ..

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

Указание "статического" зависит от того, как вы используете программу.

person Raghu Srikanth Reddy    schedule 29.12.2012