您的问题似乎确实源于臭名昭著的静态初始化命令惨败。
基本上,当您在一个翻译单元中有一个static 变量X,在第二个翻译单元中引用另一个static 变量Y,那么您的程序有50/50 的错误行为机会。为了正常运行,Y 应该在 X 之前初始化,但 C++ 不强制这样做。
据我所知,处理此问题的唯一正确方法是使用函数级 static 变量,这确保 m_array 将在首次调用 MyClass::array() 时被初始化(以及在 C++11这个初始化甚至保证是线程安全的):
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());
}
};
换句话说,您应该避免声明 static 全局变量或类变量(除非您绝对确定它们可以解析为编译时常量,例如上面的 arraySize),但是换行它们在 static 函数内部的函数级别。
附带说明一下,这个习惯用法使您可以更轻松地使用适当的容器而不是传统的 C 数组,例如。 std::vector 或者,如果你使用 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;
}
};