C++ 全局变量初始化顺序

标签 c++ variables initialization declaration definition

我不明白以下代码示例的作用以及它是如何做到的:

#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/

相关文章:

c++ - 在没有事件异常的情况下终止调用(多线程合并排序)

c++ - 通过符号链接(symbolic link)包含共享库会导致 undefined reference

c++ - 为什么 iostream::eof 在循环条件(即 `while (!stream.eof())` )内被认为是错误的?

ios - 为方便初始化而失败的初始化程序失败

java - 如何在 Java 7 中使用一组众所周知的值初始化无符号字节数组?

c++ - boost::local_time 未读取正确的 iso_extended_format

Javascript:如何动态定位变量

JavaScript 变量定义 : Commas vs. 分号

c# - "composite"变量类型的正确实现是什么?

c++ - 通过构造函数在类中初始化二维数组