静态存储中的内联变量何时初始化? [英] When are inline variables in static storage initialized?
问题描述
C ++标准(至少早于C ++ 17)已经说明了有关初始化顺序.
C++ standards (earlier than C++17, at least) have said this about initialization order.
具有在相同翻译单元中的名称空间范围内定义并动态初始化的具有静态存储持续时间的对象,应按照其定义在翻译单元中出现的顺序进行初始化.
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++17 introduces inline variables, which I believe to mean that a single variable with static storage duration and namespace scope and dynamic initialization could be defined in multiple translation units.
C ++是否可以保证这些变量的初始化顺序?
Does C++ make any guarantees about the initialization order of these variables?
推荐答案
请参见[basic.start.dynamic] p1:
See [basic.start.dynamic] p1:
具有静态存储持续时间的非局部变量的动态初始化是无序的(如果该变量是隐式或显式实例化的特殊化),如果该变量是不是隐式或显式实例化的内联变量,则该动态局部化是无序的;并且否则将被订购.
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:
Therefore, the type of variable you are describing has "partially-ordered initialization". According to p2:
具有静态存储持续时间的非局部变量
V
和W
的动态初始化的顺序如下:
Dynamic initialization of non-local variables
V
andW
with static storage duration are ordered as follows:
- ...
- 如果
V
具有部分有序的初始化,则W
没有无序的初始化,并且V
定义在W 之前每个定义了
W
的翻译单元中的code>,然后- 如果程序启动了除主线程(6.6.1)之外的其他线程(4.7),则
V
的初始化强烈地发生在W
的初始化之前; - 否则,
V
的初始化在W
的初始化之前进行排序.
- ...
- 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
.
总结一下,假设图片中没有实例化的模板:
So to summarize, assuming that there are no instantiated templates in the picture:
- 如果您有两个命名空间范围的内联变量
V
和W
,以便在W
之前定义V
在每个翻译单元中,然后在W
之前先初始化V
. - 如果只有
V
是内联的,并且W
是仅在一个翻译单元中定义的一些非内联的命名空间范围变量,则V
将只要在该翻译单元中V
的定义在W
的定义之前,就可以在W
之前初始化. - 如果在行内变量之前定义了非行内变量,则不能保证其初始化顺序.
- If you have two namespace-scope inline variables
V
andW
such thatV
is defined beforeW
in every translation unit, thenV
is initialized beforeW
. - If only
V
is inline, andW
is some non-inline namespace-scope variable defined in exactly one translation unit,V
will be initialized beforeW
as long asV
's definition precedesW
's in that one translation unit. - If the non-inline variable is defined before the inline variable, their initialization order cannot be guaranteed.
一种考虑初始化顺序的直观方法是,就像在C ++ 14中一样,编译器按顺序初始化每个翻译单元,而未指定不同翻译单元的相对顺序(并且它们可以相互交错),但具有外部链接的内联变量被认为是在实施命中"第一次时初始化的.它的定义之一,可以在任何翻译单位中使用.
An intuitive way to think about initialization order is that, just as in C++14, the compiler initializes each translation unit in order, with the relative ordering of different translation units unspecified (and they can be interleaved with each other), but an inline variable with external linkage is considered to be initialized the first time the implementation "hits" one of its definitions which may be in any translation unit.
另请参阅p5:
是否动态初始化带有静态变量的非本地内联变量是由实现定义的存储持续时间在
main
的第一条语句之前排序或延迟.如果推迟,则强烈发生在该变量的任何非初始化odr使用之前.它是由实现定义的,其中哪个线程以及在程序中的哪一点发生了这种延迟的动态初始化.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.这篇关于静态存储中的内联变量何时初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- if the program starts a thread (4.7) other than the main thread (6.6.1), the initialization of
- 如果程序启动了除主线程(6.6.1)之外的其他线程(4.7),则