So I'm reading that for Zero Initialization will initialize:
Every named variable with static or thread-local storage duration that is not subject to constant initialization, before any other initialization
I am using a Singleton with the traditional private constructor and a static public method in which there is a local static singleton object which the method will be return.
My problem is that the class also has a static vector
which is zero-initialized and it seems to be getting initialized after the singleton, meaning that I cannot interact with it. Is there something that governs this initialization order or is that simply implementation defined?
This is a simplification of what my code looks like:
class Foo {
Foo(){ s_vec.push_back(13); }
public:
static Foo& Get() {
static Foo singleton;
return singleton;
}
int Front() const { return s_vec.front(); }
static vector<int> s_vec;
};
vector<int> Foo::s_vec;
I'm running into this problem because elsewhere in the code I'm initializing a static global variable like this and not getting 13: static const auto element = Foo.Get().Front()
Constructor for global variables are executed before the start of main, but the order across compilation units is not specified.
The
Foo
constructor in your example should only be called once you callFoo::Get
. If the first time you call it is inmain
, the static vector will be already initialized.One situation, where you can run into the race that you describe is when you call
Foo::Get
in the initialization code of another global object, especially when the code is in another compilation unit.But in a simple test like this here, the vector should always be initialized first and there will be no possible race:
(I'm assuming
Foo::Get
is a static member in the singleton, otherwise you cannot instantiate it. But it does not make a difference conceptually.)The problematic scenario could look like this:
You have no control about the initialization order of
Foo::s_vec
(in the first compilation unit) andbar
(in the second one).