Чтобы понять разницу, вы должны ознакомиться с концепцией под названием предварительное определение в С. процитировать стандарт C:
С11, проект, §6.9. 2, внешний объект определения
декларацию о качестве идентификатора для объекта, который имеет файл сфера без инициализатора и без спецификатора класса хранения или с спецификатор класса хранения static, представляет собой предварительное определение . Если единица перевода содержит одно или несколько предварительных определений для идентификатора, а единица перевода не содержит внешнего определения для этого идентификатора, то это точно , как если бы единица трансляции содержала объявление области видимости этого идентификатора , с композит типа, как в конце блока перевода с инициализатором равным 0.
Что вы имеете в первом фрагменте лишь предварительное определение i
. Вы можете иметь столько предварительных определений для объекта, сколько хотите (но допускается только одно определение):
int i; // tentative definition
int i; // tentative definition
int i; // tentative definition
int main(void) {
return 0;
}
действителен.
У i
Внешняя связь и предварительная установка. Если i
определено где-то в одной и той же единицы перевода, то это будет фактическое определение i
.Если нет другого определения i
не найден в ЕП, то это становится полное определение, как если бы оно было определено как:
int i = 0;
int main(void) {
return 0;
}
Но второй фрагмент int i;
является не предварительное определение. Только объекты с внешней связью могут быть определены ориентировочно. Во втором фрагменте декларация extern int i;
говорит, что i
определен в другом месте с внешней связью. Но следующая строка int i;
говорит, что i
определен без привязки (локальные автоматические переменные не имеют связи - это не условное определение). Таким образом, существует конфликт определения для i
. Следовательно, первый фрагмент отлично, а второй - нет.
первый раз я столкнулся с словом «предварительное определение». Я работаю на C++, и я не думаю, что такая вещь существует. – cbinder
Да, C++ не имеет предварительных определений. –
век живи, век учись –