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

标签 c++ scope namespaces language-lawyer using-declaration

阅读来自 this question 的已接受答案后,我想我明白为什么程序失败了,因为 using 指令 ​​does not actually declare the entity i in the region .但是由 using 声明引入的名称 can be used just like any other nameacts 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/

相关文章:

mysql - 编写此日期范围范围的更好方法是什么?

javascript - 本地从canvas元素获取三个.js场景进行操作

多个文件中的 C++ 变量范围

php - 命名空间如何在 Laravel 路由组内工作

c++ - C++ 中的“助手”函数

c++ - 是否有必要在构造函数中初始化一个私有(private)列表类成员?

c++ - 如何在 Visual Studio 2012 中查看断言失败的 C++ 堆栈跟踪?

c++ - wstringstream 默认格式标志

namespaces - tcl 切换命名空间和 proc 参数

c++ - 什么是|运算符在函数调用中是什么意思? [C++]