N4424 introduces inline
variables (ones that can be defined in multiple translation units, useful in header-only libraries), but it is not in C++14. I have been using the following method to emulate it:
// a.hpp
#pragma once // to simplify
inline A& a_init() { static A a_obj; return a_obj; }
static A& a = a_init();
and
// b.hpp
#pragma once // to simplify
#include "a.hpp"
inline B& b_init() { static B b_obj{ use(a) }; return b_obj; }
static B& b = b_init();
The cpp files uses a
and b
. Nothing else uses a_init
and b_init
.
I think that:
a
must be initialized beforeb
, in every translation unit that includesb
;- As nothing else calls
b_init
,b_init
is only called when initializingb
. From 1 at that timea
must have been initialized (a_init
must have returned); a_obj
is initialized whena_init
is called, so isb_obj
forb_init
;- Combining 2 and 3,
a_obj
anda
are initialized before the calling ofb_init
, thus theuse(a)
is safe and the initialization order must beA() < B()
(A()
returns, thenB()
is called); - Destructors run in the reverse order of the completion of their construction, so
~B() < ~A()
.
Is my reasoning correct? Is this a working emulation of inline A a; inline B b{ use(a) };
and guarantees the order of A() < B() < ~B() < ~A()
?