Static local variables are initialised on the first function call:
Variables declared at block scope with the specifier static have static storage duratio
g()
is not thread-safe, and is susceptible to all sorts of ordering problems. Safety is going to come at a price. There are several ways to pay it:
f()
, the Meyer's Singleton, pays the price on every access. If accessed frequently or accessed during a performance-sensitive section of your code, then it does make sense to avoid f()
. Your processor presumably has a finite number of circuits it can devote to branch prediction, and you are being forced to read an atomic variable before the branch anyway. It is a tall price to continually pay for just ensuring that the initialization happened only once.
h()
, described below, works very much like g()
with an extra indirection, but assumes that h_init()
gets called exactly once at the beginning of execution. Preferably, you would define a subroutine that gets called as the line of main()
; that calls every function like h_init()
, with an absolute ordering. Hopefully, these objects do not need to be destructed.
Alternatively, if you use GCC, you can annotate h_init()
with __attribute__((constructor))
. I prefer the explicitness of the static init subroutine though.
A * h_global = nullptr;
void h_init() { h_global = new A { }; }
A const& h() { return *h_global; }
h2()
is just like h()
, minus the extra indirection:
alignas(alignof(A)) char h2_global [sizeof(A)] = { };
void h2_init() { new (std::begin(h2_global)) A { }; }
A const& h2() { return * reinterpret_cast (std::cbegin(h2_global)); }