Sat*_*mar 4 c static gcc static-members gnu-arm
我尝试了这三个版本的小程序,我得到了一些有趣的结果.任何人都可以帮助我了解每种情况下的编译器行为.
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>.
Run Code Online (Sandbox Code Playgroud)
在您的第一个示例中,int A;是一个暂定的定义:在没有初始化程序且没有存储类或static存储类的情况下在文件范围内声明标识符.你可以有多个,它们都会引用同一个变量:
标准说:(ISO/IEC 9899:1999 6.9.2)
具有没有初始化程序的文件范围且没有存储类说明符或存储类说明符静态的对象的标识符声明构成暂定定义.如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,则行为就像翻译单元包含该标识符的文件范围声明一样,复合类型为翻译单元的结尾,初始化程序等于0.
在第二个示例中,A不是文件范围.它是一个局部变量,它不是一个暂定的定义,所以你只能有一个.
在第三个示例中,Aat文件范围是与A内部main()不同的变量,因为它们具有不同的范围.仅仅因为第二个A是静态的并不会改变它的范围; 标识符仍然只能从main()内部看到.这是一个变量阴影的情况,其中一个作用域中的变量与封闭作用域中的变量具有相同的标识符(在本例中为main()作用域与文件作用域.)Aat文件作用域恰好是暂定的定义不会影响A内部的main().