首页 > 解决方案 > 使用外部全局变量初始化全局变量

问题描述

假设file_1.cppfile_2.cpp是一个程序中的两个文件。我遇到的情况如下:

// file_1.cpp
extern int y;  // Line 1
int z = y + 1;  // Line 2
int main() {
  cout << y << endl;  // 2
  cout << z << endl;  // probably 1, sometimes 3
}

// file_2.cpp
int x = 1;  // Line 3
int y = x + 1;  // Line 4

我的理解是,当执行在进入之前构造全局变量时main(),根据优化设置,有可能 in 的全局变量file_1.cpp是在全局变量 in 之前构造的file_2.cpp。在这种情况下, 的值y设置为0当它用于初始化z时,因此cout << z << endl;打印1Line 4file_2.cpp在进入前构造好全局变量时执行main(),所以我们还有cout << y << endl;打印出来2

我的问题:据我所知,extern int y;是一个没有定义的声明(它不分配内存,它并没有真正创建对象,它只是将名称引入程序)。所以,我想知道在Line 1/处究竟发生了什么Line 2(以防cout << z << endl;打印出来1)。真的y被定义和初始化到0那里吗?或者这只是编译器/链接器完成的优化行为,这样(在初始化期间z)每当看到令牌时y,它就会被值替换0

如果y真的在/处定义(并初始化为0),它让我感到困惑,因为它与我的理解相矛盾,这只是一个声明,在这种情况下,我想知道编译器/链接器如何在稍后执行时避免重新定义。Line 1Line 2extern int y;Line 4

我知道在实际程序中,上面的代码是我们应该避免的,但我真的很想知道它的实现。

标签: c++

解决方案


您描述的这种情况被称为“全局初始化订单惨败”。

程序启动时,所有全局变量的内存都用 0 填充(即每个字节为 0)。在下一阶段,执行所有全局变量的构造函数或初始化。每个文件中这些初始化的顺序由该文件中变量定义的顺序决定,但文件的顺序是任意的。

在您的示例中,y初始化为file_2.cpp. file_1.cpp如果之前执行了 中定义的变量的初始化,则file_2.cpp得到z==1.

extern int y;实际上,第 1 行与初始化顺序无关 - 它只允许访问y.file_1.cpp


推荐阅读