C ++标准(至少早于C ++ 17)已经说明了有关初始化顺序。
具有在同一翻译单元中的名称空间范围内定义并动态初始化的具有静态存储持续时间的对象,应按照其定义在翻译单元中出现的顺序进行初始化。
C ++ 17引入了inline variables,我相信这意味着具有静态存储持续时间和命名空间范围以及动态初始化的单个变量可以用多个翻译单元定义。
C ++是否可以保证这些变量的初始化顺序?
答案 0 :(得分:4)
请参见[basic.start.dynamic] p1:
具有静态存储持续时间的非局部变量的动态初始化是无序的(如果该变量是隐式或显式实例化的特殊化),如果该变量是不是隐式或显式实例化的内联变量,则该动态局部化是无序的;并且否则被订购。
因此,您描述的变量类型具有“部分排序的初始化”。根据p2:
具有静态存储持续时间的非局部变量
V
和W
的动态初始化的顺序如下:
- ...
- 如果
V
具有部分有序的初始化,则W
没有无序的初始化,并且V
在每个{{1} },然后
- 如果程序启动了除主线程(6.6.1)之外的线程(4.7),则
W
的初始化强烈地发生在W
的初始化之前;- 否则,
V
的初始化在W
的初始化之前进行排序。- ...
总结一下,假设图片中没有实例化的模板:
V
和W
,因此在每个翻译单元中的V
之前都定义了W
,则V
为在W
之前初始化。V
是内联的,并且W
是仅在一个转换单元中定义的一些非内联命名空间范围变量,则V
将在W
之前初始化为只要V
的定义在该翻译单元的W
之前。另请参阅p5:
是否动态初始化带有静态变量的非本地内联变量是实现定义的 存储持续时间在
V
的第一个语句之前排序或被延迟。如果推迟,则强烈 在对该变量进行任何非初始化odr使用之前发生。它由实现定义在哪个线程中 以及在程序中的哪一点发生了这种延迟的动态初始化。