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

Global variables in C ++ 11 with non-trivial constructors are built before being entered into main during the static initialization phase.

Similarly, non-functional local thread_local variables are created during the thread_local initialization phase on the thread.

Does the C ++ 11 standard indicate in which order these variables should be built? In both cases, if there are two variables:

// global scope A::A() { bf(); } // A constructor uses global b A a; B b; 

Does the C ++ 11 standard indicate in which order they should be initialized, or that an error should be generated if the variable is used uninitialized?

Similarly for non-function-local thread_local:

 // global scope A::A() { bf(); } // A constructor uses global b thread_local A a; thread_local B b; 

Does the standard indicate the order that should be constructed, and does it determine what happens if the variable is used from the constructor of another before it is initialized?

Can you provide a standard C ++ 11 link in support of any statements you make to get an answer.

+4
source share
2 answers

Your statement that "Global variables in C ++ 11 with non-trivial constructors are built before entering the ground state during the static initialization phase." does not seem completely true - they cannot be initialized until the dynamic initialization phase

For “ordered initialization” variables that have your first a and b, then the standard says

Variables with ordered initialization defined in one translation unit must be initialized in the order of their definition in the translation unit.

3.6.2 / 2 covers all of this.

Edit: as far as I can tell, your second a and b do not have ordered initialization and can be initialized in any order. But I may have missed something.

+2
source

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 these object definitions. The compiler is allowed to initialize b instead of static initialization if it can figure out how (on 3.6.2 / 3). Thus, the first program may or may not cause undefined behavior, and this is probably a bad idea.

For the duration of dynamic storage, note 3.7.2 / 2:

A variable with the duration of storage of the stream must be initialized before its first use odr (3.2) and, if constructed, must be destroyed when the stream exits.

Thus, local flow variables are more like function-local static variables than static namespace variables. The second program does not have undefined behavior.

+2
source

Source: https://habr.com/ru/post/1442614/


All Articles