翻译单元中的`static`定义和`extern声明`的顺序

时间:2013-08-09 07:41:30

标签: c static extern

我无法理解为什么这不起作用。

extern int i;

int main()
{
  printf(" %d ", i);  
}

static int i =3;

此外,这不起作用:

extern int i;

static int i =3;

int main()
{
  printf(" %d ", i);  
}

但如果在static之前定义了extern declaration变量:

static int i =3;

extern int i;

int main()
{
  printf(" %d ", i);  
}

我从extern int i了解到,i出现其他地方,此处看起来如何(int i

但是,其他地方意味着:

1)也许,稍后将same翻译单元指向global variable

2)也许,在一些other翻译单元中。

我认为即使(1)static int i = 3的范围限制在定义它的当前翻译单元,i也会有效。

不是static int i =3 global(我的意思是至少它在翻译单元中可见),即使它的翻译单元的范围有限吗?那么为什么编译器无法找到它呢?

当我编译前两个版本时,我得到以下编译时错误:

 error: static declaration of ‘i’ follows non-static declaration
 note: previous declaration of ‘i’ was here

我无法理解此错误消息。另外,为什么它以静态declaration来抱怨它也不是definition

3 个答案:

答案 0 :(得分:6)

C11 6.2.2 标识符的链接第4节

  

对于在其范围内使用存储类说明符extern声明的标识符   该标识符的先前声明是可见的,31)如果先前声明指定内部或外部链接,则后一声明中的标识符的链接与先前声明中指定的链接相同。如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。

因此第二个声明将遵循第一个声明,回到您的示例,第一个和第二个示例i将具有extern存储类。编译器认为这是一个错误。

在第3个示例中,i将为static,因为static首先显示。那应该没问题。

并且,在C11的第7节中6.2.2 标识符的链接

  

如果在翻译单元内,同一标识符同时显示内部和外部   联系,行为未定义。

因此,最好不要在同一翻译单元中同时使用staticextern声明相同的变量。

答案 1 :(得分:2)

嗯,变量是externstatic。请注意,static在全局范围内仅限制其对当前翻译单元的可见性,而extern则表示它在不同的翻译单元中可见。

答案 2 :(得分:0)

将某些内容声明为static并再次声明为extern是没有意义的。这样做是不明确的行为,所以不要这样做。