编译时静态可变分辨率 [英] static variable resolution at build time
问题描述
我有连结在一起的档案:
basic.h
#pragma once
extern const string APPLICATION_NAME;
application.cpp
#includebasic.h
const string APPLICATION_NAME =MyApplication;
............
ErrorTables.h
class ErrorTable
{
public:
ErrorTable();
private:
map< index,errorRecord> _errorTable;
};
ErrorTables.cpp
#includebasic.h
ErrorTable TheErrorTable;
ErrorTable :: ErrorTable()
{
...
_errorTable [errorIndex] = errorRecord(APPLICATION_NAME +碰到一些错误。
...
}
可以在Visual Studio中构建并运行此代码。
当我使用GCC时,可以编译但运行时失败。
问题在于TheErrorTable具有静态链接并且在main()启动之前创建
;它无法解析APPLICATION_NAME变量。
如果我使用局部变量隐藏它,一切正常。
是否有一个GCC标志强制在构建时期解析静态变量或
以其他方式实现Visual Studio的行为?
问题出在
具有静态链接并且在main()启动之前创建的TheErrorTable
;它无法解析APPLICATION_NAME
变量。
没错。 TheErrorTable
或 APPLICATION_NAME
会先初始化,
$ b
制作 ErrorTable
不是成为全球性的。您无法定义跨TU的静态初始化顺序,即使您只是让代码更难以遵循。
我讨厌这么说,但 ErrorTable
可能受益于此处的单例模式(因为函数 - static
s有合理的初始化订单),至少是最接近现有代码的解决方案。
更新
正如@ godexsoft提到的那样,您可以利用常量初始化并使 char const *
而不是 ErrorTable
之前保证。 (真的吗?是的。)
I have files that are linked together:
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.");
...
}
This code can be built and run OK in Visual Studio. When I use GCC, it can be build but failed in run time. The problem is in TheErrorTable that has static linkage and is created before main() is started; it can't resolve APPLICATION_NAME variable. If I hide it using local variable everything works OK.
Is there a GCC flag that force resolution of a static variable during build time or implements behavior of Visual Studio in some other way?
The problem is in
TheErrorTable
that has static linkage and is created before main() is started; it can't resolveAPPLICATION_NAME
variable.
That's right. Either TheErrorTable
or APPLICATION_NAME
is initialised first, and you can't fix this.
Make ErrorTable
not be a global. You cannot define the order of static initialisation across TUs, and even if you could you'd just be making the code harder to follow.
I hate to say it, but ErrorTable
might benefit from the singleton pattern here (because function-static
s have sane initialisation order), at least in as much as that it's the solution closest to your existing code.
Update
As @godexsoft alluded to, you can get around this by taking advantage of constant initialisation and making APPLICATION_NAME
a char const*
rather than a std::string
; your initialiser will then be a constant-expression initialiser without a constructor call, and as such will be invoked — across TUs — before any ErrorTable
, guaranteed. (Really? Yes.)
这篇关于编译时静态可变分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!