1

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具有链接的an。如果编译器找不到,则i应该在其他翻译单元中定义。所以这两者i应该在上面的代码片段中引用同一个对象。

来自标准的报价:

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

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

4

3 回答 3

7

#3只是一个声明;它声明一个名为的变量i存在于程序中的某处,具有外部链接,但没有定义该变量。该声明允许您#1g.

您还需要在包含g. 在这种情况下,它必须在不同的翻译单元中,这样它就不会与同名的静态变量冲突。

需要明确的是,这里调用了两个不同的变量i,如示例后面的段落中所述。#1在这里定义;#3仅声明,需要单独定义。

于 2013-04-16T14:31:11.470 回答
2
static int i = 0; // #1
void g() {
    extern int i; // #3 external linkage
}

第一个static i是声明,仅在当前源文件中可见。

extern int i; 

告诉编译器我不是这个意思,static i而是另一个i在其他地方定义的意思。如果您没有在其他地方(在另一个翻译单元中)定义它,您将获得未定义的参考。

这不会破坏 ODR,因为它 (the static)i是静态的(仅在本单元中可见)。

于 2013-04-16T14:34:39.237 回答
1
extern int i;

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

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

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

于 2013-04-16T14:53:14.130 回答