构建时的静态变量分辨率

时间:2012-01-05 21:08:22

标签: c++ gcc

我有链接在一起的文件:

basic.h

#pragma once

extern const string APPLICATION_NAME;

application.cpp

#include "basic.h"

const string APPLICATION_NAME = "MyApplication";

............

ErrorTables.h

class ErrorTable
{
public:
    ErrorTable();

private:
    map <index, errorRecord> _errorTable;


};

ErrorTables.cpp

#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的行为?

1 个答案:

答案 0 :(得分:2)

  

问题出在TheErrorTable,它具有静态链接,并在main()启动之前创建;它无法解析APPLICATION_NAME变量。

没错。 TheErrorTable APPLICATION_NAME首先被初始化,你无法解决这个问题。


ErrorTable 成为全球性的。你无法定义TU中静态初始化的顺序,即使你可以只是让代码更难来跟随。

我讨厌这样说,但是ErrorTable可能会受益于这里的单例模式(因为函数 - static具有合理的初始化顺序),至少在最接近于它的解决方案中是这样。你现有的代码。


更新

正如@godexsoft所提到的,你可以通过利用常量初始化并使APPLICATION_NAME成为char const*而不是std::string来解决这个问题。然后,你的初始化程序将是一个不带构造函数调用的常量表达式初始化程序,因此将在任何ErrorTable之前调用 - 在TU之前 - 保证。 (Really? Yes.