4

我尝试了这三个版本的小程序,得到了一些有趣的结果。谁能帮我理解每种情况下的编译器行为。

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>. 
4

1 回答 1

8

在您的第一个示例中,int A;是一个暂定定义:在文件范围内声明标识符,没有初始化程序,也没有存储类或static存储类。你可以有多个,它们都将引用同一个变量:

标准说:(ISO/IEC 9899:1999 6.9.2)

具有文件范围的对象的标识符声明没有初始化程序,并且没有存储类说明符或具有存储类说明符 static,构成暂定定义。如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,则行为与翻译单元包含该标识符的文件范围声明完全相同,复合类型为翻译单元的末尾,初始化器等于 0。

在您的第二个示例中,A不是文件范围。它是一个局部变量,它不是一个暂定的定义,所以你只能有一个。

在您的第三个示例中,Aat 文件范围是与A内部 main() 不同的变量,因为它们具有不同的范围。仅仅因为第二个A是静态的并不会改变它的范围;标识符仍然只能从 main() 内部看到。这是变量遮蔽的情况,其中一个范围内的变量与封闭范围内的变量具有相同的标识符(在这种情况下是 main() 范围与文件范围。)文件范围的事实A恰好是暂定定义不影响A内部 main()。

于 2013-01-17T11:26:11.007 回答