Your problem seems indeed to stem from the infamous static initialization order fiasco.
Basically, when you have a static
variable X
in one translation unit, referring to another static
variable Y
in a second translation unit, then your program has 50/50 chances of misbehaving. In order to behave properly, Y
should be initialized before X
but C++ doesn't enforce that.
As far as I know, the only proper way to handle this is to use function-level static
variables, which ensure that m_array
will be initialized on first call of MyClass::array()
(and in C++11 this initialization is even guaranteed to be thread-safe):
struct MyClass {
static const size_t arraySize = 4;
// This function could be defined in a .cpp rather than inline
// I only put it inside the class for compactness/readability reasons
static const std::string* array() {
static const std::string m_array[arraySize] = {"", "ini", "txt", "bmp"};
return m_array;
}
};
// In some other file
struct OtherClass {
// This function could be defined in a .cpp rather than inline
static void whatever() {
do_something_with(MyClass::array());
}
};
In other words, you should avoid declaring static
global or class variables (unless you are absolutely sure they can be resolved to compile-time constants, like arraySize
above), but wrap them at function-level inside static
functions.
As a side note, this idiom makes it much easier for you to use a proper container rather than a legacy C array, eg. std::vector
or, if you are using C++11, std::array
:
// C++03
struct MyClass {
// This function could be defined in a .cpp rather than inline
static const std::vector<std::string>& data() {
static std::vector<std::string> m_data;
if (m_data.empty()) {
m_data.push_back("");
m_data.push_back("ini");
m_data.push_back("txt");
m_data.push_back("bmp");
}
return m_data;
}
};
// C++11
struct MyClass {
using Container = std::vector<std::string>;
// or
// using Container = std::array<std::string, 4>;
// This function could be defined in a .cpp rather than inline
static const Container& data() {
static const Container m_data = {"", "ini", "txt", "bmp"};
return m_data;
}
};