如果全局变量初始化两次(静态初始化,然后动态初始化),哪一次初始化开始其生命周期?

2022-03-07 00:00:00 language-lawyer c++

灵感来自this question。

我们知道具有非constexpr初始值设定项的全局变量会经历两种不同的";初始化:

  • 首先,静电初始化&q;,这将对它们进行零初始化。
  • 第二,";动态初始化";,它使用用户提供的初始值设定项。

哪些初始化启动了变量LIFEST?[basic.life]无济于事:

对象的生命周期.开始时间:.其初始化(如果有)已完成

我看到几个选项:

  1. 上次初始化开始生存期。
  2. 第一次初始化开始生存期。
  3. 每次连续初始化都会销毁现有对象,并在其位置创建一个新对象。

(1)最有意义,但它会使稍后动态初始化的对象的静电初始化几乎毫无用处。

(2)会有有趣的效果。例如,静电初始化订单惨败突然不再是优步(本身)了。

(3)会非常奇怪。


解决方案

由于另一个答案仅在非规范性脚注上进行论证,我将根据非规范性注解提出反驳。并不是说我相信这种解释而不是另一种解释,但我认为该标准充其量在这里存在非规范性冲突。

[basic.start.static]/3的Note 2给出了一个未指定、未定义的行为示例,其中允许实现者(遵循[basic.start.static]/3)执行静电/线程存储持续时间变量的初始化,即使在静电初始化期间(可能是在动态初始化期间)也不需要初始化静电/线程存储持续时间变量。这里的关键是注释的示例,即为什么obj1的值未指定:即用于初始化它的对象的值可以是";完全初始化&q;或";仅仅是零初始化&q;:

[注意2:因此,如果对象obj1的初始化引用可能需要动态 初始化且稍后在同一翻译单元中定义,则为 未指定obj2使用的值是否为 完全初始化的obj2(因为obj2是静态的 已初始化)或将仅为obj2的值 零初始化。例如,

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;     // unspecified:
                    // either statically initialized to 0.0 or
                    // dynamically initialized to 0.0 if d1 is
                    // dynamically initialized, or 1.0 otherwise
double d1 = fd();   // either initialized statically or dynamically to 1.0

-结束备注]

特别是示例代码片段中的注释:

[D2]如果d1是动态初始化,则静态初始化为0.0或动态初始化为0.0,否则1.0

暗示";否则";情况,即d1是从";仅为零初始化的";d2(动态)初始化的情况并非未定义。

相关文章