【问题标题】:Can initialization order of global variables across TUs be forced with C++17 inline members?是否可以使用 C++17 内联成员强制跨 TU 的全局变量的初始化顺序?
【发布时间】:2020-09-18 16:17:46
【问题描述】:

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

根据我在答案中的介绍,内联静态成员变量按照它们的类在源代码中出现的顺序进行初始化如果这样的顺序在它们所在的所有翻译单元 (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) 之后被初始化?

结果:

  • g++ 10.1.0: x1=1 a=2 x2=3 b=4 x3=5 y1=6 y2=7 y3=8 z1=9 z2=10

  • clang++ 10.0.0: a=1 b=2 x1=3 x2=4 x3=5 y1=6 y2=7 y3=8 z1=9 z2=10

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

如果 V 和 W 已经有序初始化并且 V 的定义在 W 的定义之前是有序的,或者如果 V 有部分有序的初始化,则 W 没有无序初始化,并且对于 W 的每个定义 E 都存在V 的定义 D 使得 D 在 E 之前按外观排序,则

我读错了这一段吗?我不太确定 ors 和 ands。

【问题讨论】:

标签: c++ c++17 language-lawyer


【解决方案1】:

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

// 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之前被初始化。

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

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

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

VW 已排序初始化,V 的定义在 W 的定义之前出现排序,

“或”

V 具有部分有序的初始化,W 没有无序的初始化,并且对于W 的每个定义E 都存在V 的定义D 使得D 是外观-在E之前订购

第一个条件不满足,因为V 的外观没有排在W 之前。第二个条件也不满足,因为VW 都只有一个定义,而且正如我所说,它们不是按外观排序的。

【讨论】:

  • 哦,非常感谢您的详尽解释,毕竟我确实读错了。
猜你喜欢
  • 2022-11-13
  • 2022-09-17
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多