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



C++标准(至少早于 C++17(已经这样说了初始化顺序。

在同一翻译单元

的命名空间范围内定义静态存储持续时间并动态初始化的对象应按照其定义在翻译单元中出现的顺序进行初始化。

C++17 引入了内联变量,我认为这意味着可以在多个翻译单元中定义具有静态存储持续时间命名空间范围以及动态初始化的单个变量。

C++对这些变量的初始化顺序做出任何保证吗?

参见 [basic.start.dynamic] p1:

如果具有静态存储持续时间的非局部变量是隐式或显式实例化的专用化,则动态初始化是

无序的;如果变量是不是隐式或显式实例化的内联变量,则动态初始化是部分有序的,否则是有序的。

因此,您描述的变量类型具有"部分顺序初始化"。根据p2:

具有静态存储持续时间的非局部变量VW的动态初始化顺序如下:

  • 如果V具有部分顺序初始化,W没有无序初始化,并且在定义W的每个翻译单元中W之前定义V,则
    • 如果程序启动主线程(6.6.1(以外的线程(4.7(,则V的初始化强烈发生在W初始化之前;
    • 否则,V的初始化在初始化之前进行W的排序。

总而言之,假设图片中没有实例化的模板:

  • 如果有两个命名空间范围的内联变量VW,以便在每个翻译单元的W之前定义V,则VW之前初始化。
  • 如果只有V是内联的,并且W是一个翻译单元中定义的一些非内联命名空间范围的变量,那么只要V的定义在该翻译单元中先于WV就会在W之前初始化。
  • 如果非行内变量是在行变量之前定义的,则无法保证其初始化顺序。

考虑初始化顺序的一种直观方法是,就像在 C++14 中一样,编译器按顺序初始化每个翻译单元,未指定不同翻译单元的相对顺序(它们可以相互交错(,但是具有外部链接的内联变量在实现第一次"命中"其定义之一时被视为初始化,该定义可能位于任何翻译单元中。

另请参阅第 5 页:

实现定义是否动态初始化非局部内联变量与静态 存储持续时间在第一个语句main之前排序或延迟。如果推迟,则强烈 在使用该变量的任何非初始化 ODR 之前发生。它是实现定义的线程 以及在程序中的哪些点发生这种延迟的动态初始化。

相关内容

  • 没有找到相关文章

最新更新