I was told to use the singleton pattern instead of having global objects, which have the “static” storage duration, to avoid the static initialization order fiasco. But now that I have C++20 modules, should I?
Static initialization order fiasco
The static initialization order fiasco refers to the ambiguity in the order that objects with static storage duration in different translation units are initialized in. If an object in one translation unit relies on an object in another translation unit already being initialized, a crash can occur if the compiler decides to initialize them in the wrong order. For example, the order in which
.cpp
files are specified on the command line may alter this order. The Construct on First Use Idiom can be used to avoid the static initialization order fiasco and ensure that all objects are initialized in the correct order.Within a single translation unit, the fiasco does not apply because the objects are initialized from top to bottom.
Storage duration
“static” storage duration.
The storage for the object is allocated when the program begins and deallocated when the program ends. Only one instance of the object exists. All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with
static
orextern
. See “Non-local variables” and “Static local variables” for details on initialization of objects with this storage duration.
As far as I know…
The “static initialization order fiasco” means that which objects with the “static” storage duration, such as global objects, in non-module .cpp
files get initialized earlier is ambiguous. It might lead to a crash where an uninitialized global object is used. Many adopted the singleton pattern that features “construct on first use (lazy construction)” to avoid this.
Then, with C++20 modules…
The dependencies between C++ module files (“translation units”) are seemingly clear with the import
statements in them. Does the static initialization order fiasco matters and do I still have to use the singleton pattern, instead of having import
-able objects declared at the top level in C++ modules?
std::cout
works as expected. If I needed a solution to a similar problem I would do whatstd::cout
does. en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter – Pahang