【发布时间】:2013-04-09 00:23:15
【问题描述】:
C++11 标准在下面给出了代码 sn-p(我删除了不相关的代码)并说名称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在上面的sn-p代码中应该是指同一个对象。
引用标准:
如果有一个实体的可见声明,其链接具有 相同的名称和类型,忽略在最里面声明的实体 封闭命名空间范围,块范围声明声明 相同的实体并接收前一个声明的链接。如果 没有找到匹配的实体,块范围实体接收外部 链接。
但是为什么人们需要这个功能呢?
【问题讨论】:
-
这不是来自 IS C++11 §3.5p6 的示例。实际示例包含一个额外的块作用域
int i;,这就是为什么实际示例中的extern int i;具有external 而不是internal 链接的原因。 -
@dyp,示例中的附加块不会改变第二个
i的链接。请再次查看已接受的答案。 -
他们在标准中引入新块的原因在answers here中进行了解释。
-
@neonxc 链接的答案是关于 C 编程语言的。我相信这是 C 和 C++ 不同的情况。 This is the example from the C++11 Standard 编译为 C - 它被拒绝。但是标准声明它是合法的 C++ 并且
extern int i;变量具有外部链接。它不会更改static int i = 0;在命名空间范围内的链接,而是声明一个不同 实体。顺便说一句,根据当前的 C++ 规则,相同的示例是非法的。 [待续] -
@neonxc C++11: "如果存在具有相同名称和类型的链接的实体的可见声明,则忽略在最里面的封闭命名空间范围之外声明的实体,块范围声明声明了相同的实体并接收前一个声明的链接。” 但是 C++11 示例中的附加块作用域
int i;(参见上面的链接)隐藏命名空间-范围static int i = 0;。因此extern int i;不是指同一个对象。在 C++ 的较新版本中,这已被视为非法(同一 TU 中的同名内部+外部链接)。