Consider the following example:
tt.h declares a global constant with external linkages extern int g_TRAGIC;
tt.cpp defines g_TRAGIC as follows const int g_TRAGIC = 0xF001;
my.cpp wants to use it to define its own global constant const int g_MAGIC = g_TRAGIC;
As I read the iso-FAQ I would assume that this results in static initialization order fiasco. However the iso-FAQ notes
The static initialization order fiasco can also, in some cases, apply to built-in/intrinsic types.
What does that some cases mean? Under which conditions are we save and sound from SIOF for built-in/intrinsic types, in particular constants? Or must that Construct On First Use Idiom be used for all constants with external linkage?
Note: In the real code I can not change the definition of g_TRAGIC.
Compilers can produce different sorts of code.
The compiler emits into a data section a name and its initial value.
.data
dw myData 6
This is initialized at compile time, and is safely defined throughout the life of the program
Another alternative is for the compiler to reserve some space for the variable, and create an initializer/constructor for the data, and then call the constructor just before main
. With the destructor (if required) being performed atexit
.
class CriticalSection {
CRITICAL_SECTION m_myCS;
public:
CriticalSection() {
InitializeCriticalSection( &m_myCS );
}
~CriticalSection() {
DeleteCriticalSection( & m_myCS );
}
} cs;
Some data may be performed in both stages.
struct Data {
bool initialized;
void *(*pMalloc)( size_t size );
} FixMalloc = { true, MyMalloc };
I have seen compilers (VS2013) produce code which initializes initialized
to true in the static data, but creates a function to assign pMalloc
to MyMalloc
at runtime. (This was because there was not a known constant for MyMalloc.)
SomeClass * GetSomeClass()
{
static SomeClass cls;
return &cls;
}
This is order defined - when it gets called, but requires a fully C++11
compiler to be thread safe.
The guarantees are :-
The guarantees are not :-
Before main is called, both your statics and the C/C++ runtime are bootstrapping. The order of construction issues also occur between your code and the runtime, and so you may construct some items with complex constructors which rely on services which can't be available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With