In C++11 (and forward), the construction of the function local static AppSettings is guaranteed to be thread-safe. Note: Visual Studio did not implement this aspect of C++11 until VS-2015.
The compiler will lay down a hidden flag along side of AppSettings that indicates whether it is:
- Not constructed.
- Being constructed.
- Is constructed.
The first thread through will find the flag set to "not constructed" and attempt to construct the object. Upon successful construction the flag will be set to "is constructed". If another thread comes along and finds the flag set to "being constructed", it will wait until the flag is set to "is constructed".
If the construction fails with an exception, the flag will be set to "not constructed", and construction will be retried on the next pass through (either on the same thread or a different thread).
The object instance will remain constructed for the remainder of your program, until main() returns, at which time instance will be destructed.
Every time any thread of execution passes through AppSettings::GetInstance(), it will reference the exact same object.
In C++98/03, the construction was not guaranteed to be thread safe.
If the constructor of AppSettings recursively enters AppSettings::GetInstance(), the behavior is undefined.
If the compiler can see how to construct instance "at compile time", it is allowed to.
If AppSettings has a constexpr constructor (the one used to construct instance), and the instance is qualified with constexpr, the compiler is required to construct instance at compile time. If instance is constructed at compile time, the "not-constructed/constructed" flag will be optimized away.