我尝试了这三个版本的小程序,我得到了一些有趣的结果。任何人都可以帮助我了解每种情况下编译器的行为。
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>.
在您的第一个示例中,int A;
是一个暂定定义:在文件范围内声明一个标识符,没有初始化式,也没有存储类或static
存储类。可以有多个,它们都指向同一个变量:
标准规定:(ISO/IEC 9899:1999 6.9.2)
对于具有文件作用域且没有初始化式、没有存储类说明符或具有静态存储类说明符的对象,声明标识符构成试探性定义。如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,那么这种行为就完全像翻译单元包含该标识符的文件作用域声明一样,在翻译单元的末尾使用复合类型,初始化式等于0。
在第二个示例中,A
不属于文件作用域。它是一个局部变量,它不是一个暂定的定义,所以你只能有一个。
在您的第三个示例中,A
at文件作用域与main()中的A
是一个不同的变量,因为它们具有不同的作用域。仅仅因为第二个A
是静态的并不会改变它的作用域;标识符仍然只能在main()中可见。这是变量遮蔽的一种情况,其中一个作用域中的变量与封闭作用域中的变量具有相同的标识符(在这种情况下是main()作用域与文件作用域)。
A
恰好是一个暂定的定义,这并不影响main()中的A
。