块范围外部声明

时间:2013-04-16 14:26:50

标签: c++ c++11

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应该引用上面代码段中的相同对象。

标准的引用:

  

如果有一个有链接的实体的可见声明   相同的名称和类型,忽略在最里面之外声明的实体   封闭命名空间范围,块范围声明声明   同一实体并接收先前声明的链接。如果   找不到匹配的实体,块范围实体接收外部   键。

但为什么人们需要这个功能?

3 个答案:

答案 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,因为这(statici是静态的(仅在此单元中可见)。

答案 2 :(得分:1)

extern int i;

Promises编译器我会给你一个int i

static int i=0;不是承诺变量,你必须在int i变量声明可见的其他地方声明extern

换句话说,extern int i;static int i=0;是两个无关的变量。