我在头文件中有extern const
字符串声明,并且在源文件中有它的定义:
// a.h
extern const std::string base;
// a.cpp
const std::string base = "base";
然后我在另一个头文件中有另一个extern const
字符串,并且此字符串的定义使用第一个字符串的定义:
// b.h
extern const std::string usage;
// b.cpp
const std::string usage = base + " str";
启动应用程序时出现此错误:
动态链接库(DLL)初始化例程失败。
我将调试器附加到应用程序,并引发了以下异常:
抛出异常:读取访问冲突。这是nullptr。
[在base
中的b.cpp
处抛出。因此,我收集了这是静态初始化顺序的问题。但是在我的文件中,我在a.obj
之前列出了b.obj
,所以我不知道为什么会这样。
请注意,我仅在Windows上收到此错误。 Linux很好。
一种补救方法是在头文件中定义base
:
// a.h
const std::string base = "base";
// a.cpp
这是唯一的解决方案吗?还是有更好的方法?
[不确定标题为何提到静态字符串初始化,并且此行为可能取决于所使用的编译器,但对于vs2017,应在b.cpp文件中包含a.h标头。它为我工作。谢谢。
您可以通过#pragma init_seg
控制初始化的顺序
<< [c ++]的指针默认在#pragma init_seg
节中初始化(在.CRT$XCU
的__xc_a
和.CRT$XCA
的__xc_z
之间)所以可以成为下一个解决方案
.CRT$XCZ
和
// a.cpp
#pragma warning(disable : 4075)
#pragma init_seg(".CRT$XCU1")
const std::string base = "base";
因此将// b.cpp #pragma warning(disable : 4075) #pragma init_seg(".CRT$XCU2") const std::string usage = base + " str";
设置为base
,将".CRT$XCU1"
设置为usage
,以确保".CRT$XCU2"
将在base
之前被初始化