C++ 关于使用声明c++;

C++ 关于使用声明c++;,c++,scope,namespaces,language-lawyer,using-declaration,C++,Scope,Namespaces,Language Lawyer,Using Declaration,在阅读了来自的已接受答案后,我认为我理解了程序失败的原因,因为using指令。但是,名称是由使用声明和 对于GCC,这是失败的 #include <iostream> namespace X { int i = 1; } using X::i; int main() { extern int i; i = 2; std::cout<<i; } #包括 命名空间X{int i=1;} 使用X::i; int main(){ 外部国际一级;

在阅读了来自的已接受答案后,我认为我理解了程序失败的原因,因为using指令。但是,名称是由使用声明和

对于GCC,这是失败的

#include <iostream>


namespace X { int i = 1; }

using X::i;

int main() {
    extern int i;
    i = 2;
    std::cout<<i;
}
#包括
命名空间X{int i=1;}
使用X::i;
int main(){
外部国际一级;
i=2;

从技术上讲,您给出的示例可以编译,但无法链接。问题在于行

extern int i;
你在这里告诉编译器/链接器的是“在程序的其他地方会定义一个变量
i
,因此,编译器,如果你找不到定义,请不要担心。链接器,我希望你找到
i
的定义,一旦你有了所有的对象文件并链接到这里。”

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

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

mov     DWORD PTR i[rip], 2
但是如果没有外部声明,我们会

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

虽然我不完全确定隐藏部分,因为gcc和clang都没有警告过
-Wshadow
。在任何情况下,我们现在看到了第二个示例无法链接的原因:链接器试图找到
I
的定义以在这里使用,而
X::I
是在全局范围内定义的,
I
不是。

HmmSVC接受第一个,但clang cl不接受。仅供参考-我没有投反对票。我只是为其他人添加了一点额外的信息。@AdrianMole抱歉,我没有指责你,我只是不知道还有其他人可以添加这些。如果你有建设性的批评,我将不胜感激。在大约10分钟内2次没有太多解释的否决票有点令人沮丧.NP.DVs对我和你来说都是一个谜。但是投票是匿名的,要求解释通常是徒劳的。@AdrianMole叹了口气,一旦这个问题有两张反对票,就没有人会去看它了,所以我不仅失去了我的一点声誉,没有太多的解释,我可能不会得到更多的信息还有。有时在这里问问题会让人沮丧,我花了很多精力来具体说明,引用其他来源/问题并提供例子。我不明白我做错了什么。
mov     DWORD PTR X::i[rip], 2