extern类说明符

时间:2014-10-14 10:45:38

标签: c

如果我有这样的外部变量:

int a;

是正确的,声明等于:

extern int a = 0;

而不等于:

extern int;

是否与本地变量相同,其中写的内容如下:

int local;

等于:

auto int local;

在这两种情况下,编译器是否默认设置了说明符externauto

4 个答案:

答案 0 :(得分:4)

extern int a在文件范围声明变量但不定义它。这样的声明基本上表示该变量可以在另一个编译单元中找到,并且链接器的工作是在合并各个目标文件时解析其地址。在这种情况下省略extern定义当前单位中的变量,并将其初始值设置为0(暂定定义)。除非使用extern,否则这样定义的变量将具有外部链接(无论static被省略)。

extern int a = 0定义extern没有意义,因为您告诉编译器在这里初始化变量。在这种情况下,可以安全地省略extern

是否与auto相同?在某种程度上,externauto都是存储类说明符,是的。但是,自动变量(无论是否使用该关键字定义)不会隐式初始化。使用未初始化的auto变量是未定义的行为。此外,声明函数中的变量是不可能的,因此这里的混淆要少得多。

答案 1 :(得分:4)

关联和外部定义的规则有点奇怪,部分原因是出于历史原因(参见例如this C89理由)。对象的规则(它们对于函数声明是不同的)是:

在文件范围:

  • autoregister是不允许的,需要诊断 1)
  • static表示内部联系 2),声明是(暂定)定义 3)
  • extern表示已声明的链接,如果没有声明,则外部链接 4)
  • 没有存储类说明符表示外部链接 5),声明是(暂定)定义 6)
  • 如果多个声明在链接上不一致,则行为未定义 7)(Gcc中止编译,我想大多数编译器也是如此)。

暂定定义意味着,对象将在同一个翻译单元中定义,如果没有明确的定义,则假定0 8)多个显式定义是约束违规用于内部联系的标识符;对于具有外部链接的标识符,行为未定义(Gcc中止编译)。 9)

前两个例子主要是,但不完全等同。

int a;

a有外部联系。宣言是一个暂定的定义;如果没有显式初始化,则将其初始化为0.如果存在另一个声明static int a;,则行为将是未定义的。

extern int a = 0;

另一方面,只有当外部声明已经可见或者没有可见时,才会声明a具有外部链接。如果之后是a的静态声明,则行为未定义;如果这之前是一个,则链接将是内部的。此声明还将a初始化为0,不允许在翻译单元中显示其他明确定义。

extern int a;

(我假设extern int a;而不是extern int;。如果你的确意味着后者:那是违反约束条款。)

这是一个(外部的,如果没有其他声明可见)声明没有定义。通常,定义出现在另一个翻译单元中。如果标识符用于评估它的表达式,它必须出现在某处。

在块范围内:

  • extern表示与文件范围相同,但没有暂定定义。不允许初始化。 10)
  • static表示没有链接(但是静态存储持续时间)。 11)如果没有初始化,则将其初始化为0(一次,在程序启动时)。 12)
  • auto或者没有意味着没有联系。如果没有初始化 13),变量的值是不确定的,读取这样的值是不确定的(不完全,但实际上)。
  • registerauto相同,但取其地址是违反约束的。
  • 对于没有链接的标识符(表示对象),不允许重新声明。 14)

因此,最后两个例子是等效的。

此处未提及的两个存储类说明符是typedef和(自C11开始)_Thread_local 15)

参考C11(n1570):

1) 6.9 p2。 2) 6.2.2 p3。 3) 6.9.2 p2。 4) 6.2.2 p4。 5) 6.2.2 p5。 6) 6.9.2 p2。 7) 6.2.2 p7 8) 6.9.2 p2。 9) 6.9 p3和p5。 10) 6.2.2 p4和6.7.9 p5。 11) 6.2.2 p6。 12) 13) 6.7.9 p10。 14)6.7 p3。 15)参见6.7.1。

答案 2 :(得分:2)

在此文件中实例化全局变量:

int a;     // instantiation
int a = 0; // instantiation and initialization

编译期间将解析全局变量的地址。


告诉编译器全局变量在另一个文件中实例化:

extern int a;

全局变量的地址将在链接期间解析。


使用extern int a = 0,您强制a的实例化,从而使extern无用。

答案 3 :(得分:0)

int a;和extern int a = 0;是平等的。当我们初始化一个extern变量时,也会为该变量分配内存,即也会出现与int a;类似的定义。 有关extern的更多信息,请参阅http://www.geeksforgeeks.org/understanding-extern-keyword-in-c