静态存储中的内联变量何时初始化?

6

C++标准(早于C++17)对初始化顺序有如下规定:

在同一翻译单元中以命名空间作用域定义、需要动态初始化的具有静态存储期的对象应按照它们在翻译单元中的定义顺序进行初始化。

C++17 引入了 内联变量,我认为这意味着一个具有静态存储期、命名空间作用域和动态初始化的变量可以在多个翻译单元中被定义。

C++是否保证这些变量的初始化顺序?

1个回答

5
请参考[basic.start.dynamic] p1:
具有静态存储期的非局部变量的动态初始化,如果该变量是隐式或显式实例化的特化,则是无序的;如果该变量是不是隐式或显式实例化的特化的内联变量,则是部分有序的;否则是有序的。
因此,您描述的变量类型具有“部分有序初始化”。 根据p2:
具有静态存储期的非局部变量的动态初始化按以下顺序排序:
- … - 如果V具有部分有序初始化,W没有无序初始化,并且在定义W的每个翻译单位中定义V之前,则
- 如果程序启动了除主线程之外的线程(4.7),则V的初始化强制发生在W的初始化之前; - 否则,V的初始化在W的初始化之前有序。
- …
因此,总结一下,假设图片中没有实例化的模板:
- 如果您有两个命名空间范围的内联变量V和W,使得在每个翻译单元中定义W之前定义V,则V将在W之前初始化。 - 如果仅V是内联变量,并且W是在一个翻译单元中定义的某些非内联命名空间范围变量,则只要V的定义在该翻译单元中W的定义之前,则V将在W之前初始化。 - 如果非内联变量在内联变量之前定义,则不能保证它们的初始化顺序。
初始化顺序的直观思考方式是,就像在C++14中一样,编译器按顺序初始化每个翻译单元,不同翻译单元之间的相对顺序未指定(它们可以与彼此交错),但具有外部链接的内联变量被视为在实现“命中”其定义的第一次初始化,可能在任何翻译单元中。
另请参见p5:
是否对具有静态存储期的非局部内联变量的动态初始化在main的第一条语句之前排序或延迟排序是实现定义的。如果延迟排序,它强制发生在该变量的任何非初始化odr使用之前。该延迟动态初始化发生在程序中的哪些线程和哪些点上是实现定义的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接