【问题标题】:block scope extern declaration块作用域外部声明
【发布时间】: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 中的同名内部+外部链接)。

标签: c++ c++11


【解决方案1】:

#3 只是一个声明;它指出程序中存在一个名为i 的变量,具有外部链接,但没有定义该变量。该声明允许您在g 的范围内使用它,而不是来自#1 的静态变量。

您还需要在包含g 的命名空间中定义它。在这种情况下,它必须位于不同的翻译单元中,以免与同名的静态变量冲突。

为了清楚起见,这里有两个不同的变量,称为i,如示例后面的段落中所述。 #1 在这里定义; #3 只是声明的,需要单独定义。

【讨论】:

  • 但实际上这两个i指的是同一个对象(至少在vs2012中)。
  • 如果是这样,那么编译器是错误的。示例后面的段落清楚地解释了它们是分开的。它开始于“此程序中有三个名为 i 的对象。”
  • @Mike (OP) 你说 VS2012 抱怨一个未解析的符号(即带有外部链接的 i)。这意味着它们相同的i
  • @huskerchad 我的意思是,如果我在其他地方使用该名称,就会出现该错误。
  • 这听起来不像是解释为什么 i 具有外部链接,即使它被定义为在 #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 是静态的(仅在本单元中可见)。

【讨论】:

    【解决方案3】:
    extern int i;
    

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

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

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

    【讨论】:

    • are two irrelevant variables. 到底是什么意思
    • @SebNag:也许我的措辞不准确,但this sample 说明了我的意思
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2015-08-11
    • 2019-06-25
    • 2022-08-04
    • 2016-05-19
    • 2012-03-19
    • 1970-01-01
    相关资源
    最近更新 更多