c++ - 在局部作用域中使用 extern 取消全局变量的阴影是否有效?

标签 c++ global-variables extern local-variables

嵌套局部作用域中的这个 extern 声明是将全局 a 带回作用域的有效且已定义的方法吗?

int a = 1; // may be in another file
void main() {
    int a = 2; // hides the global
    {
     cout << a << endl;  // prints 2
     cout << ::a << endl; // obviously 1
     extern int a;
     cout << a << endl;  // also prints 1
    }
}

最佳答案

这是 extern 的有效用法,尽管是一种晦涩难懂的用法。根据C++20标准([basic.link]/6):

The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If such a declaration is attached to a named module, the program is ill-formed. If there is a visible declaration of an entity with linkage, ignoring entities declared outside the innermost enclosing namespace scope, such that the block scope declaration would be a (possibly ill-formed) redeclaration if the two declarations appeared in the same declarative region, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage. If, within a translation unit, the same entity is declared with both internal and external linkage, the program is ill-formed.

在OP的示例中, block 作用域声明extern int a;无法找到具有链接的匹配声明,因为本地声明int a = 2;没有链接隐藏了具有外部链接的全局声明int a = 1;。因此,extern int a; 默认为外部链接。另请参阅第 7 段:

When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope.

因此,extern int a;a 声明为最近的封闭命名空间(即全局命名空间)的成员。这意味着它与之前声明的全局 a 是相同的实体,因为两者都通过链接在同一命名空间中声明了一个具有相同名称的变量。换句话说,它为您提供了一种引用 block 内的全局变量的方法。

extern 的这种用法是从 C 继承的,但即使在 C 中也很晦涩。通常应避免使用它,而应使用 ::a

关于c++ - 在局部作用域中使用 extern 取消全局变量的阴影是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69572326/

相关文章:

c++ - 是否有用于 Debian/Ubuntu 的 Boost 1.5.3 软件包?

c++ - 编译错误: cannot find -lGLU and -lGL in kubuntu linux

c++ - 为什么在使用 operator class_name() & c 样式转换时 g++ 会出现错误

python - 将 Python 函数中的所有变量设为全局变量

lua - 在lua中访问全局变量

c++ - 以特定顺序扩展可变参数模板值的最有效方法是什么?

python - "exec expr in globals(), locals()"的分配顺序出乎意料

c++ - C++ 如何区分对全局变量的调用和全局变量的声明?

c - 外部声明的数组和指针版本之间的差异

c - 具有分层控制的函数指针使用: xtern/namespace C++