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

时间:2019-08-09 21:52:16

标签: c++ c++17 initialization-order inline-variable

C ++标准(至少早于C ++ 17)已经说明了有关初始化顺序。

  

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

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

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

1 个答案:

答案 0 :(得分:4)

请参见[basic.start.dynamic] p1:

  

具有静态存储持续时间的非局部变量的动态初始化是无序的(如果该变量是隐式或显式实例化的特殊化),如果该变量是不是隐式或显式实例化的内联变量,则该动态局部化是无序的;并且否则被订购。

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

  

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

     
      
  • ...
  •   
  • 如果V具有部分有序的初始化,则W没有无序的初始化,并且V在每个{{1} },然后      
        
    • 如果程序启动了除主线程(6.6.1)之外的线程(4.7),则W的初始化强烈地发生在W的初始化之前;
    •   
    • 否则,V的初始化在W的初始化之前进行排序。
    •   
  •   
  • ...
  •   

总结一下,假设图片中没有实例化的模板:

  • 如果您有两个命名空间范围内联变量VW,因此在每个翻译单元中的V之前都定义了W,则V为在W之前初始化。
  • 如果仅V是内联的,并且W是仅在一个转换单元中定义的一些非内联命名空间范围变量,则V将在W之前初始化为只要V的定义在该翻译单元的W之前。
  • 如果在行内变量之前定义了非行内变量,则不能保证其初始化顺序。 (本质上,您可以想象实现会选择以某种顺序初始化翻译单元;它可能会在仅包含内联变量的翻译单元之一选择同时包含内联变量和非内联变量的翻译单元之前。)

另请参阅p5:

  

是否动态初始化带有静态变量的非本地内联变量是实现定义的   存储持续时间在V的第一个语句之前排序或被延迟。如果推迟,则强烈   在对该变量进行任何非初始化odr使用之前发生。它由实现定义在哪个线程中   以及在程序中的哪一点发生了这种延迟的动态初始化。