When creating a Singleton causes undefined behavior in older C++.
A common way to create a Singleton (a class with only one instance) in C++ is to declare a static local variable inside a function. Because it's static, it is only initialized the first time the function is called (Lazy Initialization). But before C++11, if two threads called the function at the exact same time, the compiler did not guarantee thread safety. Thread B might see a half-constructed object!
In C++11 and later, the standard explicitly mandates that the initialization of block-scope static variables is thread-safe. The compiler automatically inserts hidden locking and Double-Checked Locking logic for you. This safe pattern is known as the Meyers Singleton.
// The Meyers Singleton
class Database {
public:
static Database& get_instance() {
// In C++11 and later, this is 100% thread-safe.
// The compiler secretly adds locks around this initialization.
static Database instance;
return instance;
}
private:
Database() {} // Private constructor
};
The cost in modern C++ is extremely low. The compiler optimizes the hidden locks so that after the first initialization, subsequent calls are lock-free and branch-predicted. It is the gold standard for Singletons in C++.