我不明白以下代码示例的作用以及它是如何做到的:
#include <stdio.h>
int f();
int a = f(); // a exists just to call f
int x = 22;
int f() {
++x;
return 123; // unimportant arbitrary number
}
int main() {
printf("%d\n", x);
}
运行时会打印出 23
,这是直观的答案。
但是在 C++ 中,全局变量是 supposed to be按定义顺序初始化。这意味着 a
应该在 x
之前初始化,因为它是在 x
之前定义的。如果是这种情况,那么函数 f
必须在 x
初始化之前被调用,因为对 f
的调用是a
的定义。
如果在 x
初始化之前确实调用了 f
,这意味着 f
会尝试增加 x
- 我不确定的结果(很可能是 UB,或者一些乱码)。然后,a
初始化后,x
会被初始化为22
,程序会打印出22
。
显然不是这样。但有什么作用?该代码实际上做了什么?
在评估 a = f()
之前,似乎 x
设置为 22
,但这意味着初始化是相反的(我也可能对初始化是什么或何时发生有误)。
最佳答案
这个问题有点微妙;详情请引用C++11 3.6.2。
对我们来说重要的是“具有静态存储持续时间的非局部变量”(或通俗的说法是“全局变量”)的初始化有两个阶段:静态初始化阶段和动态初始化阶段。静态阶段首先出现。它看起来像这样:
int a = 0;
int x = 22;
动态初始化之后运行:
a = f();
关键是静态初始化根本不会“运行”——它只包含在编译时已知的设置值,因此这些值在任何执行发生之前就已经设置好了。使初始化 int x = 22;
静态的原因在于初始化程序是一个常量表达式。
在某些情况下,动态初始化可能被提升到静态阶段(但不是必须),但这不是其中一种情况,因为它不满足要求 p>
the dynamic version of the initialization does not change the value of any other object of namespace scope prior to its initialization
当这种提升发生时,产生的初始值可以与没有发生时不同。标准中有一个这样的“不确定”初始化示例。
关于C++ 全局变量初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22117310/