I\'d have expected the following code to yield a segmentation fault (or otherwise UB):
struct T {
T();
};
T t;
char const* str = \"Test string\";
T::T()
I think I found it; what's happening here is not so much about the built-in type, but about the constant initialiser:
[C++11: 3.6.2/2]:
Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.Constant initialization is 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.
Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place. [..]
That final sentence would seem to override subsequent sequencing rules, making this ordering apply across Translation Units.
char const* str = "Test string";
is done by the compiler/linker, so it exists in its "initialized state" before the program even starts to run.
Built-in types aren't initialised at all, in the normal sense. Commonly, their initial contents are memory-mapped directly from a special region of the binary as part of loading it.
str
is initialized by a constant expression and const char *
is a POD type (C++03 terms, but C++11 it is analogous, but with different terms and way more allowed cases). Such an initialization is done in static initialization phase, and the static initialization phase has no issue of order. It happens before any dynamic initialization. t
is initialized in the dynamic initialization phase.