阅读来自 this question 的已接受答案后,我想我明白为什么程序失败了,因为 using 指令 does not actually declare the entity i
in the region .但是由 using 声明引入的名称 can be used just like any other name和 acts like a declaration .
使用 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;
}
最佳答案
从技术上讲,您给出的示例确实可以编译,但无法链接。问题是线路
extern int i;
你在这里告诉编译器/链接器是“将有一个变量 i
在程序的其他地方定义,所以,编译器,如果你找不到定义,不要担心。链接器,我希望你能找到 i
的定义,一旦您拥有所有目标文件并将其链接到此处。”我们可以使用编译器资源管理器看到这一点:
Without the extern declaration
With the extern declaration
在第二种情况下,声明
i
“阴影”X::i
这是在全局范围内可见的,所以我们得到了指令mov DWORD PTR i[rip], 2
而没有 extern 声明,我们得到mov DWORD PTR X::i[rip], 2
虽然我不完全确定阴影部分,因为 gcc 和 clang 都没有警告 -Wshadow
.无论如何,我们现在明白为什么第二个例子无法链接了:链接器试图找到 i
的定义。在这里使用,而同时使用 X::i
在全局范围内定义,i
不是。
关于c++ - 关于使用声明 C++ 的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65924397/