Понимание множественного объявления переменной в программе и поведения компилятора GCC
Я попробовал эти три версии небольшой программы и получил несколько интересных результатов. Может кто-нибудь, пожалуйста, помогите мне понять поведение компилятора в каждом случае.
version 1.0
int A;
int A;
int A;
int main ()
{
return 0;
}
Result: Got compiled with one copy of A in BSS.
Version 2.0
int main ()
{
int A;
int A;
int A;
return 0;
}
Result: Failed to compile with complaining for re-declaration.
Version 3.0
int A;
int main()
{
static int A;
return0;
}
result: Compiled with two copy of A in BSS. one is A and another a.<some numeric tag>.
1 ответ
В вашем первом примере int A;
это предварительное определение: объявление идентификатора в области видимости файла без инициализатора и без класса хранения или static
класс хранения. Вы можете иметь несколько из них, и все они будут ссылаться на одну и ту же переменную:
Стандарт гласит: (ISO/IEC 9899:1999 6.9.2)
Объявление идентификатора для объекта, который имеет область файла без инициализатора и без спецификатора класса хранения или со статическим спецификатором класса хранения, составляет предварительное определение. Если модуль перевода содержит одно или несколько предварительных определений для идентификатора, а модуль перевода не содержит внешних определений для этого идентификатора, то поведение точно такое, как если бы модуль перевода содержал объявление области файла для этого идентификатора с составным типом как конца блока перевода, с инициализатором, равным 0.
Во втором примере A
не относится к области файлов. Это локальная переменная, и это не предварительное определение, поэтому вы можете иметь только одну.
В вашем третьем примере A
в области видимости файла это другая переменная, чем A
внутри main(), так как они имеют разные области видимости. Просто потому что второй A
статичен, не меняет сферу действия; идентификатор все еще виден только изнутри main(). Это случай теневого копирования переменных, когда переменная в одной области имеет тот же идентификатор, что и переменная в области видимости (в этом случае область main () и область действия файла). A
на уровне файла оказывается предварительное определение не влияет на A
внутри main().