静态存储中的内联变量什么时候初始化?
When are inline variables in static storage initialized?
C++ 标准(至少早于 C++17)已经对初始化顺序进行了说明。
Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit.
C++17 引入了 ,我认为这意味着具有 静态存储持续时间 和 命名空间范围 [=22] 的单个变量=] 和 动态初始化 可以在 多个翻译单元 .
中定义
C++对这些变量的初始化顺序有什么保证吗?
参见 [basic.start.dynamic] 第 1 页:
Dynamic initialization of a non-local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization, is partially-ordered if the variable is an inline variable that is not an implicitly or explicitly instantiated specialization, and otherwise is ordered.
因此,您所描述的变量类型具有“部分顺序初始化”。根据 p2:
Dynamic initialization of non-local variables V
and W
with static storage duration are ordered as follows:
- ...
- If
V
has partially-ordered initialization, W
does not have unordered initialization, and V
is defined before W
in every translation unit in which W
is defined, then
- if the program starts a thread (4.7) other than the main thread (6.6.1), the initialization of
V
strongly happens before the initialization of W
;
- otherwise, the initialization of
V
is sequenced before the initialization of W
.
- ...
所以总结一下,假设图中没有实例化的模板:
- 如果您有两个名称空间范围的内联变量
V
和 W
,这样 V
在每个翻译单元的 W
之前定义,那么 V
在 W
. 之前初始化
- 如果只有
V
是内联的,而 W
是在恰好一个翻译单元中定义的某个非内联命名空间范围变量,则 V
将在 [=11= 之前初始化] 只要 V
的定义在那个翻译单元中位于 W
之前。
- 如果非内联变量定义在内联变量之前,则不能保证它们的初始化顺序。
考虑初始化顺序的一种直观方法是,就像在 C++14 中一样,编译器按顺序初始化每个翻译单元,未指定不同翻译单元的相对顺序(并且它们可以与每个翻译单元交错其他),但是具有外部链接的内联变量被认为是在实现第一次“命中”其定义之一时被初始化,该定义可能在任何翻译单元中。
另见第 5 页:
It is implementation-defined whether the dynamic initialization of a non-local inline variable with static
storage duration is sequenced before the first statement of main
or is deferred. If it is deferred, it strongly
happens before any non-initialization odr-use of that variable. It is implementation-defined in which threads
and at which points in the program such deferred dynamic initialization occurs.
C++ 标准(至少早于 C++17)已经对初始化顺序进行了说明。
Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit.
C++17 引入了
C++对这些变量的初始化顺序有什么保证吗?
参见 [basic.start.dynamic] 第 1 页:
Dynamic initialization of a non-local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization, is partially-ordered if the variable is an inline variable that is not an implicitly or explicitly instantiated specialization, and otherwise is ordered.
因此,您所描述的变量类型具有“部分顺序初始化”。根据 p2:
Dynamic initialization of non-local variables
V
andW
with static storage duration are ordered as follows:
- ...
- If
V
has partially-ordered initialization,W
does not have unordered initialization, andV
is defined beforeW
in every translation unit in whichW
is defined, then
- if the program starts a thread (4.7) other than the main thread (6.6.1), the initialization of
V
strongly happens before the initialization ofW
;- otherwise, the initialization of
V
is sequenced before the initialization ofW
.- ...
所以总结一下,假设图中没有实例化的模板:
- 如果您有两个名称空间范围的内联变量
V
和W
,这样V
在每个翻译单元的W
之前定义,那么V
在W
. 之前初始化
- 如果只有
V
是内联的,而W
是在恰好一个翻译单元中定义的某个非内联命名空间范围变量,则V
将在 [=11= 之前初始化] 只要V
的定义在那个翻译单元中位于W
之前。 - 如果非内联变量定义在内联变量之前,则不能保证它们的初始化顺序。
考虑初始化顺序的一种直观方法是,就像在 C++14 中一样,编译器按顺序初始化每个翻译单元,未指定不同翻译单元的相对顺序(并且它们可以与每个翻译单元交错其他),但是具有外部链接的内联变量被认为是在实现第一次“命中”其定义之一时被初始化,该定义可能在任何翻译单元中。
另见第 5 页:
It is implementation-defined whether the dynamic initialization of a non-local inline variable with static storage duration is sequenced before the first statement of
main
or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of that variable. It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.