C ++编译器如何找到extern变量? [英] How do c++ compilers find an extern variable?

查看:139
本文介绍了C ++编译器如何找到extern变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用g ++和clang ++编译该程序.有一个区别:
g ++打印1,而clang ++打印2.
看来
g ++:extern变量在最短范围内定义.
clang ++:extern变量是在最短的全局范围内定义的.

I compile this program by g++ and clang++. There has a difference:
g++ prints 1, but clang++ prints 2.
It seems that
g++: the extern varible is defined in the shortest scope.
clang++: the extern varible is defined in the shortest global scope.

C ++规范对此有任何规范吗?

Does C++ spec has any specification about that?

main.cpp

#include <iostream>
static int i;
static int *p = &i;

int main() {
  int i;
  {
    extern int i;
    i = 1;
    *p = 2;
    std::cout << i << std::endl;
  }
}

other.cpp

other.cpp

int i;

版本:g ++:7.4.0/clang ++:10.0.0
编译:$(CXX)main.cpp other.cpp -o extern.exe

version: g++: 7.4.0/ clang++:10.0.0
compilation: $(CXX) main.cpp other.cpp -o extern.exe

推荐答案

[基本.link/7] 应该是本标准的相关部分.在当前草案中,它表示:

[basic.link/7] should be the relevant part of the Standard. In the current draft, it says:

在块作用域中声明的函数的名称与在块作用域 extern 声明中声明的变量的名称具有链接.如果将这样的声明附加到命名模块,则程序格式错误.如果存在具有链接的实体的可见声明,则忽略在最内层封闭的命名空间范围之外声明的实体,这样,如果两个声明出现在同一声明性区域中,则块范围声明将是(可能是格式错误的)重新声明.块作用域声明声明同一实体,并接收先前声明的链接.如果存在多个这样的匹配实体,则程序格式错误.否则,如果未找到匹配实体,则块作用域实体将接收外部链接.如果在翻译单位内使用内部和外部链接声明同一实体,则程序格式错误.

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.

请注意,后面的示例几乎完全符合您的情况:

Note that the subsequent example almost exactly matches your case:

static void f();
extern "C" void h();
static int i = 0;               // #1
void g() {
  extern void f();              // internal linkage
  extern void h();              // C language linkage
  int i;                        // #2: i has no linkage
  {
    extern void f();            // internal linkage
    extern int i;               // #3: external linkage, ill-formed
  }
}

因此,该程序应格式错误.示例下面是解释:

So, the program should be ill-formed. The explanation is below the example:

在第2行没有声明的情况下,在第3行的声明将与在第1行的声明链接.由于带有内部链接的声明是隐藏的,因此,#3具有外部链接,从而使程序格式错误.

Without the declaration at line #2, the declaration at line #3 would link with the declaration at line #1. Because the declaration with internal linkage is hidden, however, #3 is given external linkage, making the program ill-formed.

这篇关于C ++编译器如何找到extern变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆