[basic.start.dynamic] (original) (raw)

6 Basics [basic]

6.9 Program execution [basic.exec]

6.9.3 Start and termination [basic.start]

6.9.3.3 Dynamic initialization of non-block variables [basic.start.dynamic]

Dynamic initialization of a non-block 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.

[Note 1:

A non-inline explicit specialization of a templated variable has ordered initialization.

— _end note_]

A declaration D isappearance-ordered before a declaration E if

in either case prior to E.

Dynamic initialization of non-block variables V and Wwith static storage duration are ordered as follows:

[Note 2:

This definition permits initialization of a sequence of ordered variables concurrently with another sequence.

— _end note_]

A non-initialization odr-useis an odr-use ([basic.def.odr]) not caused directly or indirectly by the initialization of a non-block static or thread storage duration variable.

It is implementation-defined whether the dynamic initialization of a non-block non-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 any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized.38

It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.

Recommended practice: An implementation should choose such points in a way that allows the programmer to avoid deadlocks.

[Example 1: #include "a.h" #include "b.h"B b; A::A() { b.Use();} #include "a.h"A a;#include "a.h" #include "b.h" extern A a;extern B b;int main() { a.Use(); b.Use();}

It is implementation-defined whether either a or b is initialized before main is entered or whether the initializations are delayed until a is first odr-used inmain.

In particular, if a is initialized beforemain is entered, it is not guaranteed that b will be initialized before it is odr-used by the initialization of a, that is, before A​::​A is called.

If, however, a is initialized at some point after the first statement of main, b will be initialized prior to its use in A​::​A.

— _end example_]

It is implementation-defined whether the dynamic initialization of a non-block 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 is implementation-defined whether the dynamic initialization of a non-block non-inline variable with thread storage duration is sequenced before the first statement of the initial function of a thread or is deferred.

If it is deferred, the initialization associated with the entity for thread _t_is sequenced before the first non-initialization odr-use by _t_of any non-inline variable with thread storage duration defined in the same translation unit as the variable to be initialized.

It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.

If the initialization of a non-block variable with static or thread storage duration exits via an exception, the function std​::​terminate is called ([except.terminate]).