全局变量初始化两次?

时间:2012-02-17 09:37:19

标签: c++ global-variables

file1.cpp

#include <iostream>

extern int u;
int i=9;
int j=i+9;
int main()
{
   std::cout<<u;
   return 0;
}

file2.cpp

extern int j;
int u=j+9;

结果是u = 9但不是27

这表明j被初始化两次 - 第一个零(由于variable u获得值9)然后是18

有可能吗?我的初始化意义在这里被破坏了。

我也试着让variable j保持不变,看看接下来会发生什么

file1.cpp //将j更改为常量

extern int u;
int i=9;
extern const int j=i+9;

这与以前的输出相同。

但是,如果我将int j=i+9;(在file1.cpp中)更改为int j=9;

令人惊讶的是,我得到了正确的值,即u = 18;

4 个答案:

答案 0 :(得分:4)

未指定在不同的 translation Units 中声明的全局变量的初始化顺序。

全局变量uij位于代码中的不同翻译单元中,因此u首先被初始化或i&amp; ;在j未指定之前初始化u 这将在您的代码中调用未定义的行为。
这将在您的代码中调用未指定的行为

但是,请注意,同一翻译单元中全局变量的初始化顺序是明确定义的 即:明确定义i将在代码j之前初始化。

您所看到的是 Static Initialization Fiasco 的经典案例。

答案 1 :(得分:2)

因为“i”不是“const int”,所以i + 9不是常量表达式。这使得“j”的初始化是动态的。 “你”之一也是。 “u”和“j”的动态初始化顺序未定义。所以你不知道哪个值将用于“你”。在你的情况下,你得到“j”的值,这是零初始化的结果,但在动态初始化之前,所以“j”仍为零。

如果你把“i”变为“const int”,那么你应该把正确的值变成“u”,因为“j”将会静态初始化。

答案 2 :(得分:1)

未定义全局变量在不同翻译单元中初始化的顺序。因此,如果使用另一个全局变量初始化全局变量,其中变量位于不同的转换单元中,将会发生什么未定义不能保证变量将被正确初始化,并且应该是避免。

答案 3 :(得分:1)

这就是标准所说的应该发生的事情。所有静态对象都是 在其他事情发生之前初始化为零。然后全部静止 初始化,然后所有动态初始化。在翻译中 单位,初始化发生在定义的词汇顺序; 在翻译单位之间,订单是未指定的,所以是否 (动态)初始化u在动态之前或之后 j的初始化可能会有所不同;更改您指定的顺序 命令行上的文件可能会改变代码的行为。

如果初始化是一个常量表达式,那么它就变成了 静态初始化。表达式被视为常量 表达式,其中的所有变量必须是const,必须是它们自己 用常量表达式初始化,它们的初始值设定项必须 是可见的。在您的情况下,使所有变量const都意味着 j具有静态初始化,但它不会对u执行任何操作, 因为j中的file2.cpp初始值设定项不可见。