c++ - 具有静态存储持续时间的常量初始化变量的初始化顺序

标签 c++ initialization language-lawyer static-initialization

基于以下代码片段:

const int a = 42;
const int b = a;

我们知道这两个变量都会进行常量初始化,而常量初始化就是静态初始化。

由于静态初始化的顺序是未指定的(不像动态初始化,它有指定的顺序),这是否可能导致未定义的行为,就好像 b 的静态初始化发生在 a,它会读取未初始化的内存吗?

最佳答案

首先,让我们澄清一下上下文:我们正在考虑初始化具有static 存储持续时间的变量。这个初始化实际上有两个部分:静态阶段和动态阶段。静态阶段首先发生,在这个阶段变量之间没有依赖关系。初始化顺序仅对具有静态存储的变量的动态初始化有影响。

静态变量的(动态)初始化顺序通常不是未指定的。它通常在不同的翻译单元之间未指定,并且在某些情况下也在单个 TU 内。

const int a = dynamic_init();
const int b = a;

如果这些变量在单个 TU 中,如示例所示,则指定顺序:首先声明 a,因此首先对其进行初始化。

const int a = 42;
const int b = a;

42 是常量表达式。因此 a 具有常量初始化,这是静态初始化(不是动态的)。因此,初始化顺序对此变量无关紧要。

a 也是一个常量表达式,因为a 是具有静态存储和常量初始化器的const 变量。因此 b 也有非动态初始化。因此,初始化顺序对此变量无关紧要。


不考虑上下文:

Since the order of static initialization is unspecified [...], would this not possibly result in undefined behavior, as if the static initialization of b occured before a

仅仅因为标准没有指定顺序,并不意味着实现可以为所欲为。标准说静态初始化发生,实现负责执行它。它必须选择一个按指定工作的顺序。

在实践中,顺序并不重要,因为程序无法观察到它。无论实现选择如何实现,这两个变量都被初始化为 42。

关于c++ - 具有静态存储持续时间的常量初始化变量的初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58479267/

相关文章:

c++ - 通过 tcp 构造 char*

c++ - C/C++ 中的并发日志文件访问

c++ - 使用 stringstream 将动态大小的字符串转换为整数

c - C 中未初始化指针的值

c++ - 表达式的数学定义结果

c++ - 删除 lambda 赋值运算符的基本原理?

c - 指向空函数的指针

c - 为什么下面的代码不起作用?

不使用放置新返回的指针时的 C++ 严格别名

c++ - C++ 中的存储重用