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 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.
Does C++ make any guarantees about the initialization order of these variables?
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.
Therefore, the type of variable you are describing has "partially-ordered initialization". According to 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
.- ...
So to summarize, assuming that there are no instantiated templates in the picture:
V
and W
such that V
is defined before W
in every translation unit, then V
is initialized before W
.V
is inline, and W
is some non-inline namespace-scope variable defined in exactly one translation unit, V
will be initialized before W
as long as V
's definition precedes W
's in that one translation unit.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.
Also see p5:
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.