I have a vector in a header, like so:
extern std::vector<Foo> g_vector;
In the associated cpp file I have this:
std::vector<Foo> g_vector;
I also have a class Bar
, and in it's constructor it will add some stuff to g_vector
, like so:
Bar::Bar(/* stuff */)
{
// do things
std::cout << g_vector.size() << std::endl;
g_vector.push_back(somefoo);
std::cout << g_vector.size() << std::endl;
}
If I declare a Bar
inside a function, like a sane person, it appears to work fine. However, if I want to declare a Bar
outside of a function, weird things happen. For example, I have a Bar
declared in MyFile1.cpp and in MyFile2.cpp, and because of my cout statements in Bar I can see the Foo
get pushed into the vector, but when the next Bar
runs its constructor the vector's size is 0 again. In other words, my output is
0
1
0
1
What gives? Just to be extra double sure, I also tried printing out &g_vector
to make sure it was actually push_back
ing into the right vector, and the addresses all match. For what it's worth, it doesn't matter what order these things go in to the vector. I'm not concerned with the initialization order or anything.
Not sure what the issue really is, but I guess the following pattern will help solve it: define an accessor to the global variable and allocate it as a static function variable as shown below.
In the header file:
std::vector<Foo> &getGlobalVector();
In the cpp file:
std::vector<Foo> &getGlobalVector()
{
static std::vector<Foo> s_vector;
return s_vector;
}
This pattern is inspired from Andrei Alexandrescu's "generic singleton" implementation in Modern C++ design.
I've taken the habit of systematically using this pattern whenever I fell upon an existing global variable while maintaining existing applications (or in the rare occasions I actually chose to use one myself), and it may have helped in eliminating a couple of hard-to-reproduce bugs in said applications.
At any rate, this should really help avoiding any multiple-initialization or order-of-initialization related issue.
Order of initialization of global values is not defined.
Read here about the static initialization fiasco.
When you declare Bar
in a function - the g_vector
will be initialized before, because its promised to be initialized before the program runs. If Bar
is a global variable - then you have a problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With