首页 > 解决方案 > 关于使用声明 c++ 的规则

问题描述

在阅读了这个问题的接受答案后,我想我理解了程序失败的原因,因为 using 指令实际上并未声明i该区域中的实体。然而,由 using 声明引入的名称可以像任何其他名称一样使用,并且可以像声明一样使用

使用 GCC,这会失败

#include <iostream>


namespace X { int i = 1; }

using X::i;

int main() {
    extern int i;
    i = 2;
    std::cout<<i;
}

但这被接受

#include <iostream>

int i;

int main() {
    extern int i;
    i = 2;
    std::cout<<i;
}

标签: c++scopenamespaceslanguage-lawyerusing-declaration

解决方案


从技术上讲,您给出的示例确实可以编译,但无法链接. 问题是线路

extern int i;

您在这里告诉编译器/链接器的是“i程序中的其他地方将定义一个变量,因此,编译器,如果找不到定义,请不要担心。链接器,我希望您找到定义一旦您拥有i所有目标文件并将其链接到此处。”

我们可以使用编译器资源管理器看到这一点:

没有外部声明

使用外部声明

在第二种情况下,i“阴影”的声明X::i在全局范围内可见,所以我们得到指令

mov     DWORD PTR i[rip], 2

而没有 extern 声明,我们得到

mov     DWORD PTR X::i[rip], 2

虽然我不完全确定阴影部分,因为 gcc 和 clang 都没有警告过-Wshadow. 无论如何,我们现在看到了为什么第二个示例无法链接:链接器试图在i此处找到要使用的定义,而 whileX::i是在全局范围内定义的,但i不是。


推荐阅读