C ++ 11标准给出了下面的代码片段(我删除了不相关的代码),并说名称i
具有外部链接。 (第3.5.6条)
static int i = 0; // #1
void g() {
extern int i; // #3 external linkage
}
他们为什么这样做?我误解了什么吗?两个i
引用vs2012中的相同对象。当我在其他地方使用i
时,我得到了一个未解决的外部错误。我不知道vs2012是否支持此功能。
编辑:
我认为VS2012正在做正确的事情。 #3中的i
只需要引用具有链接的i
。如果编译器找不到,则应在其他翻译单元中定义i
。因此,两个i
应该引用上面代码段中的相同对象。
标准的引用:
如果有一个有链接的实体的可见声明 相同的名称和类型,忽略在最里面之外声明的实体 封闭命名空间范围,块范围声明声明 同一实体并接收先前声明的链接。如果 找不到匹配的实体,块范围实体接收外部 键。
但为什么人们需要这个功能?
答案 0 :(得分:6)
#3
只是一个声明;它声明一个名为i
的变量存在于程序的某个地方,具有外部链接,但没有定义该变量。该声明允许您在#1
的范围内使用该声明,而不是g
中的静态变量。
您还需要在包含g
的命名空间中定义它。在这种情况下,它必须位于不同的转换单元中,以便它不会与具有相同名称的静态变量冲突。
要清楚,这里有两个不同的变量i
,如示例后面的段落所述。此处定义#1
; #3
仅被声明,需要单独的定义。
答案 1 :(得分:2)
static int i = 0; // #1
void g() {
extern int i; // #3 external linkage
}
第一个static
i
是一个声明,仅在当前源文件中可见。
extern int i;
告诉编译器我不是指static i
而是另一个i
在其他地方定义。如果您没有在其他地方(在另一个翻译单元中)定义它,您将获得未定义的引用。
这不会破坏ODR,因为这(static
)i
是静态的(仅在此单元中可见)。
答案 2 :(得分:1)
extern int i;
Promises编译器我会给你一个int i
。
static int i=0;
不是承诺变量,你必须在int i
变量声明可见的其他地方声明extern
。
换句话说,extern int i;
和static int i=0;
是两个无关的变量。