относительно использования ключевого слова extern


extern int var;
Я понимаю, что когда мы используем ключевое слово extern с переменной, как показано ниже, память для этой переменной не выделяется. (Это всего лишь заявление)
extern int i = 0;

И я знаю, что если мы объявляем переменную extern и также предоставляем инициализатор вместе с этим объявлением, то память выделяется для этой переменной.

Также ниже программа печатает 0

#include <stdio.h>
int i; // Can I treat this as declaration/definition?
int main()
{
    printf("%d ", i);
    return 0;
}

Я чувствую, что здесь переменной i присваивается значение 0.

Если (int i; как показано выше) - это определение, почему ниже код не дает множественную ошибку определения?

#include <stdio.h>
int i;
int i;
int i;
int main()
{
    printf("%d ", i);
    return 0;
}
1 3

1 ответ:

Без явной инициализации все int i s в глобальном пространстве называются предварительным определением. Однако это не допускается в локальной области.

Процитируем стандарт C11, глава §6.9.2, определения внешних объектов

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