关于使用声明 c++ 的规则

Rules regarding using declarations c++

阅读 , I thought I understood why the program failed, since the using directive does not actually declare the entity i in the region. However names introduced by a using declaration can be used just like any other name and 接受的答案后。

对于 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;
}

从技术上讲,您给出的示例 可以 编译,但无法 link。问题是行

extern int i;

你在这里告诉 compiler/linker 的是“将在程序的其他地方定义一个变量 i,所以,编译器,如果找不到,请不要担心定义。链接器,我希望你在拥有所有目标文件和 link 后找到 i 的定义。"

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

Without the extern declaration

With the extern declaration

在第二种情况下,i 的声明“遮蔽”了在全局范围内可见的 X::i,因此我们得到指令

mov     DWORD PTR i[rip], 2

而没有外部声明,我们得到

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

虽然我对阴影部分不是很确定,因为 gcc 和 clang 都没有用 -Wshadow 警告过这一点。无论如何,我们现在明白了为什么第二个例子 link 失败了:linker 试图找到 i 的定义在这里使用,而 X::i 是在全局范围内定义,i 不是。