哪个值会打印出来?

时间:2014-01-17 11:31:44

标签: c extern

void main()
{
    extern int i;
    printf("%d\n",i);
}
int i;//definetion
int i=35;//definition

在上面的代码中,int i表示i=0;int i=35表示i=35

那么为什么编译器没有给出redefinition的错误?

,会打印哪个值

2 个答案:

答案 0 :(得分:3)

在ansi标准中,他们称int x;为“暂定”定义。

这就是ansi标准所说的:

  

具有文件范围的对象的标识符声明   没有初始化程序,没有存储类说明符或没有   存储类说明符静态,构成一个暂定的   定义。如果翻译单元包含一个或多个暂定单元   标识符的定义,翻译单元包含否   该标识符的外部定义,然后行为是完全正确的   好像翻译单元包含一个文件范围声明   标识符,在翻译结束时使用复合类型   单位,初始化程序等于0。

举例:

     int i1 = 1;          /*  definition, external linkage */
     static int i2 = 2;   /*  definition, internal linkage */
     extern int i3 = 3;   /*  definition, external linkage */
     int i4;              /*  tentative definition, external linkage */
     static int i5;       /*  tentative definition, internal linkage */
     int i1;   /*  valid tentative definition, refers to previous */
     int i2;   /*  $3.1.2.2 renders undefined, linkage disagreement */
     int i3;   /*  valid tentative definition, refers to previous */
     int i4;   /*  valid tentative definition, refers to previous */
     int i5;   /*  $3.1.2.2 renders undefined, linkage disagreement */



     extern int i1; /* refers to previous, whose linkage is external */
     extern int i2; /* refers to previous, whose linkage is internal */
     extern int i3; /* refers to previous, whose linkage is external */
     extern int i4; /* refers to previous, whose linkage is external */
     extern int i5; /* refers to previous, whose linkage is internal */

在我的理解,只要你想,最多一个定义(与初始化),你可以有相同的对象尽可能多的初步定义。如果没有定义,暂定定义将转换为定义,并在文件末尾使用initializer == 0。

换句话说,打印的值是35,因为有一个初始化程序。

答案 1 :(得分:1)

从6.7.5开始:

  
    

“标识符的定义是该标识符的声明:      - 对于一个对象,导致为该对象保留存储; ......“

  

所以int i;int i = 35;都是定义(也是声明,因为所有定义都是声明)。

不同之处在于int i = 35;也有一个显式初始化器,而int i;只有在没有外部定义的情况下才会隐式初始化为0(假设全局因此是静态存储持续时间):

来自6.2.9.2:

  
    

具有没有初始化程序的文件范围的对象的标识符声明,以及     没有存储类说明符或存储类说明符静态,构成一个     暂定的定义。如果翻译单元包含一个或多个临时定义     然后,标识符和转换单元不包含该标识符的外部定义     行为就像翻译单元包含该文件范围声明一样     标识符,具有复制类型,如翻译单元的末尾,带有初始化程序     等于0。

  

请注意,这些暂定定义在c ++中不可用。 (见附录C1.2第3.1条)

因此,在这种情况下,将打印值35,因为这是i初始化的值。