C 11:STD Ref Global变量和非功能 - 局部线程界初始化订单

C++11: std ref global variable and non-function-local thread_local initialization order?

本文关键字:线程 局部 初始化 功能 STD Ref Global 变量      更新时间:2023-10-16

在静态初始化阶段进入main之前,构建了C 11中的全局变量。

同样在每线" thread_local初始化阶段"中构建了非函数 - 局部螺纹tread_local变量。

C 11标准是否应以什么顺序指定这些变量?在这两种情况下,如果有两个变量:

// global scope
A::A() { b.f(); }  // A constructor uses global b
A a;
B b;

C 11标准是否应以什么顺序进行初始化,或者如果使用一个变量,则应产生错误?

对于非功能 - 局部线程_local同样:

// global scope
A::A() { b.f(); }  // A constructor uses global b
thread_local A a;
thread_local B b;

标准是否指定必须构造它们的顺序,并且是否定义了如果变量在初始化之前从另一个构造函数使用?

之前会发生什么?

您可以提供 C 11标准参考以支持您提出的答案。

您的陈述,即在静态初始化阶段进入MAIN之前,构建了" C 11中的全局变量"。似乎不是完全正确的 - 在动态初始化阶段

之前可能不会初始化它们。

对于带有"有序初始化"的变量,您的第一个A和B是,然后标准说

变量具有单一定义的有序初始化 翻译单元应按其顺序初始化 翻译单元中的定义。

3.6.2/2涵盖了所有这些。

编辑:据我所知,您的第二个A和B没有订购的初始化,并且可以按任何顺序初始化。但是我可能缺少一些东西。

对于静态存储持续时间,我同意艾伦的答案。如果初始化在同一翻译单元中,则它们的动态初始化是这些对象定义的顺序。如果可以弄清楚如何(每3.6.2/3),则允许编译器将b初始化为静态初始化。因此,第一个程序可能会或可能不会调用未定义的行为,这可能是一个坏主意。

对于动态存储持续时间,注3.7.2/2:

应在第一次ODR使用(3.2)之前初始化带有线程存储持续时间的变量,如果构造,则应在线程出口上销毁。

因此,线程 - 本地变量的作用更像功能 - 本地静态变量,而不是命名空间静态变量。第二个程序没有不确定的行为。