In the C++11 standard the order of initialization of non-local variables is discussed in §3.6.2 “Initialization of non-local variables”.
First static initialization is performed, then dynamic initialization.
Static initialization consists of zero-initialization followed by constant-initialization. Zero-initialization is just what it sounds like. Constant-initialization is new in C++11, and §3.6.2/2 specifies that it's performed
- if each full-expression (including implicit conversions) that appears in the initializer of a reference with static or thread storage duration is a constant expression (5.19) and the reference is bound to an lvalue designating an object with static storage duration or to a temporary (see 12.2);
- if an object with static or thread storage duration is initialized by a constructor call, if the constructor is a
constexpr
constructor, if all constructor arguments are constant expressions (including conversions), and if, after function invocation substitution (7.1.5), every constructor call and full-expression in the mem-initializers and in the brace-or-equal-initializers for non-static data members is a constant expression;- if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.
So, the second point is where a constexpr
object is potentially initialized, as the last part of static initialization, and essentially it happens if everything is constexpr
so that it can be known at compile time.
And yes, as part of the static initialization this happens before dynamic initialization.