简体   繁体   中英

C++11: std ref global variable and non-function-local thread_local initialization order?

Global variables in C++11 with non-trivial constructors are constructed before the entry to main during a static initialization phase.

Likewise non-function-local thread_local variables are constructed during a per-thread "thread_local initialization phase".

Does the C++11 standard specify in what order these variables shall be constructed? In both cases if there are two variables:

// global scope

A::A() { b.f(); }  // A constructor uses global b

A a;
B b;

Does the C++11 standard specify in what order they shall be initialized, or that an error should be produced if a variable is used uninitialized?

Likewise for non-function-local thread_local:

// global scope

A::A() { b.f(); }  // A constructor uses global b

thread_local A a;
thread_local B b;

Does the standard specify the order they must be constructed, and does it define what will happen if the variable is used from the constructor of another before it is initialized?

Can you please provide a C++11 standard reference in support of any claims you make to have an answer.

Your statement that "Global variables in C++11 with non-trivial constructors are constructed before the entry to main during a static initialization phase." doesn't seem to be entirely true - they may not be initialised until the dynamic initialization phase

For variables with "ordered initialization", which your first a and b are, then the standard says

Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit.

3.6.2/2 covers all this.

Edit: as far as I can tell your second a and b don't have ordered initialization, and could be initialized in either order. But I may be missing something.

For static storage duration, I agree with Alan's answer. If the initializations are in the same translation unit, their dynamic initializations are the order of those object definitions. The compiler is allowed to initialize b as a static initialization instead if it can figure out how (per 3.6.2/3). So the first program may or may not invoke undefined behavior, and is probably a bad idea.

For dynamic storage duration, note 3.7.2/2:

A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed, shall be destroyed on thread exit.

So thread-local variables act more like function-local static variables than namespace-scope static variables. The second program does not have undefined behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM