2017-02-21 4 views
-5

Когда мы объявляем любую глобальную переменную, напримерПочему класс хранения глобальных переменных в C неявно определяется как «extern»?

int x; 

это эквивалентно

extern int x; 

Теперь по умолчанию глобальные переменные инициализируются в 0 компилятором, что означает, что они выделяются память. Но если я просто напишу

extern int x; 

тогда это только объявит переменную, в то время как память не будет выделена. Итак, мой запрос заключается в том, что если я напишу extern до int x или я его не пишу, в случае глобальных переменных, как компилятор обрабатывает их по-разному? В случае, когда я просто пишу int x, он выделяет память и одновременно ставит extern до int x, тогда как в случае, когда я пишу extern int x, он объявляет только переменную, в то время как память не выделяется. Просьба пояснить, как работает компилятор в обоих направлениях.

+1

'int x;' не эквивалентен 'extern int x;' (вы, кажется, признаете это в своем последнем абзаце) –

+0

Вопрос в том, почему вы считаете, что глобальная переменная объявлена ​​как 'extern'? –

ответ

1

На это может быть найдено определение внешнего объекта и Tentative definition.

Цитирование C11, глава §6.9.2, (курсив мой )

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

+1

Я блуждаю, почему люди все еще игнорируют тот факт, что Стандарт следует читать хотя бы один раз. – Michi

+0

@Michi Согласен. Много раз стандартный текст кажется немного сложным, но при тщательном изучении это единственный авторитетный источник, который может реально ответить на большинство вопросов. –

6

сама предпосылка вашего вопроса неверен. Это

int x; 

является предварительное определение (который превратится в нормальное определение x к концу блока перевода).

Этого

extern int x; 

не является определяющим декларации, которая не является определением вообще.

Они даже не отдаленно эквивалентны.

Ослабленный эквивалент исходного определения будет

extern int x = 0; 

Это определение. Но это не точный эквивалент, так как это определение не является предварительным.

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

Смежные вопросы