是否可以使用 C++17 内联成员强制跨 TU 的全局变量的初始化顺序?

Can initialization order of global variables across TUs be forced with C++17 inline members?

这主要是一个好奇心驱动的问题,我不打算写这样的代码。 这是 关于动态初始化顺序的跟进。

根据我在答案中给出的内容,内联静态成员变量按照它们 类 在源代码中出现的顺序进行初始化 if 这样的顺序在不同的地方是相同的它们都出现的所有翻译单元 (TU)。

此外,[basic.start.dynamic]-3.1 部分适用于偏序(其他内联静态)和有序变量。也就是同一个TU里的普通全局变量。

所以,给出这个例子:


//A.hpp
struct A{
    inline static int a=foo();// Some function with possible side-effects
};

//B.hpp
struct B{
   inline static int b=foo();
};

//X.cpp
int x1 = foo();
#include "A.hpp"
int x2 = foo();
#include "B.hpp"
int x3 = foo();

//Y.cpp
int y1 = foo();
#include "A.hpp"
int y2 = foo();
#include "B.hpp"
int y3 = foo();

变量是否按以下顺序初始化?

  1. (x1,y1)顺序未定,
  2. a,
  3. (x2,y2)顺序未定,
  4. b,
  5. (x3,y3) 顺序未定。

此外,如果翻译单元只有 类 之一,规则是否仍然适用?

//Z.cpp
int z1 = foo(); // Initialized with (x1,y1) ?
#include "A.hpp"
int z2 = foo(); // Initialized with (x2,y2) or anytime later ?

特别是,包含 A:: 是否会创建一个障碍,保证 z2(x1,y1) 之后初始化?

结果:

两个编译器至少对一组 x,y 变量打破了我的假设。我错过了什么? 我主要参考这个

If V and W have ordered initialization and the definition of V is appearance-ordered before the definition of W, or if V has partially-ordered initialization, W does not have unordered initialization, and for every definition E of W there exists a definition D of V such that D is appearance-ordered before E, then

我是不是看错了这一段?我不太确定 ors 和 ands。

让我们稍微简化一下您的示例,使其更易于理解:

// X.cpp
int x1 = foo();
inline int a = foo();
int x2 = foo();

// Y.cpp
int y1 = foo();
inline int a = foo();
int y2 = foo();

你的问题是x1是否保证在y2之前初始化,y1是否保证在x2之前初始化。

答案是否定的。正如我所解释的 动态初始化的部分排序规则的效果是,每个翻译单元的外部内联变量的“实例”在概念上被视为一个单独的变量;对象本身(只有一个)在第一次初始化时 任何 相应的名义变量都将被初始化。

例如,一个特定的排序会在 Y 翻译单元之前执行整个 X 翻译单元。在这种情况下,初始化的顺序是 x1ax2y1(没有操作,因为 a 之前已初始化),y2. (编译器同样可以在 X 中的所有内容之前对 Y 中的所有内容进行排序,或者将它们交错排列。)

引用的 [basic.start.dynamic]/3.1 来自比我在回答中考虑的更新版本的标准,但基本逻辑是相同的。让 V = x1W = y2。根据3.1,如果

V会在W之前初始化

V and W have ordered initialization and the definition of V is appearance-ordered before the definition of W,

“或”

V has partially-ordered initialization, W does not have unordered initialization, and for every definition E of W there exists a definition D of V such that D is appearance-ordered before E

不满足第一个条件,因为 V 不是 W 之前的 appearance-ordered。第二个条件也不满足,因为 VW 每个只有一个定义,正如我所说,它们不是 appearance-ordered.