我有链接在一起的文件:
#pragma once
extern const string APPLICATION_NAME;
#include "basic.h"
const string APPLICATION_NAME = "MyApplication";
............
class ErrorTable
{
public:
ErrorTable();
private:
map <index, errorRecord> _errorTable;
};
#include "basic.h"
ErrorTable TheErrorTable;
ErrorTable::ErrorTable()
{
...
_errorTable[errorIndex] = errorRecord(APPLICATION_NAME + " hit some error.");
...
}
可以在Visual Studio中构建并运行此代码。 当我使用GCC时,它可以构建但在运行时失败。 问题出现在具有静态链接的TheErrorTable中 在main()启动之前创建;它无法解析APPLICATION_NAME变量。 如果我使用局部变量隐藏它,一切正常。
是否有GCC标志强制在构建时或建立时解析静态变量 以其他方式实现Visual Studio的行为?
答案 0 :(得分:2)
问题出在
TheErrorTable
,它具有静态链接,并在main()启动之前创建;它无法解析APPLICATION_NAME
变量。
没错。 TheErrorTable
或 APPLICATION_NAME
首先被初始化,你无法解决这个问题。
让ErrorTable
不成为全球性的。你无法定义TU中静态初始化的顺序,即使你可以只是让代码更难来跟随。
我讨厌这样说,但是ErrorTable
可能会受益于这里的单例模式(因为函数 - static
具有合理的初始化顺序),至少在最接近于它的解决方案中是这样。你现有的代码。
正如@godexsoft所提到的,你可以通过利用常量初始化并使APPLICATION_NAME
成为char const*
而不是std::string
来解决这个问题。然后,你的初始化程序将是一个不带构造函数调用的常量表达式初始化程序,因此将在任何ErrorTable
之前调用 - 在TU之前 - 保证。 (Really? Yes.)