静态字符串初始化顺序问题
Static string initialization order issue
我在头文件中有 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";
在应用程序启动时出现此错误:
A dynamic link library (DLL) initialization routine failed.
我将调试器附加到应用程序,抛出以下异常:
Exception thrown: read access violation. this was nullptr.
这是在 b.cpp
中的 base
处抛出的。所以我认为这是静态初始化顺序的问题。但是在我的生成文件中,我在 b.obj
之前列出了 a.obj
,所以我不明白为什么会这样。
请注意,我仅在 Windows 时收到此错误。 Linux 没问题。
一种补救方法是在头文件中定义base
:
// a.h
const std::string base = "base";
// a.cpp
这是唯一的解决办法吗?或者有更好的方法吗?
不确定为什么标题提到了静态字符串初始化,并且这种行为可能取决于所使用的编译器,但是对于 vs2017,您应该在 b.cpp 文件中包含 a.h header。它对我有用。谢谢。
您可以使用 #pragma init_seg
控制初始化顺序
指向 c++ 的指针默认位于 .CRT$XCU
部分(介于 .CRT$XCA
的 __xc_a
和 __xc_z
之间=17=] )
所以解决方案可以是下一个
// 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
将在 usage
[=25 之前初始化=]
我在头文件中有 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";
在应用程序启动时出现此错误:
A dynamic link library (DLL) initialization routine failed.
我将调试器附加到应用程序,抛出以下异常:
Exception thrown: read access violation. this was nullptr.
这是在 b.cpp
中的 base
处抛出的。所以我认为这是静态初始化顺序的问题。但是在我的生成文件中,我在 b.obj
之前列出了 a.obj
,所以我不明白为什么会这样。
请注意,我仅在 Windows 时收到此错误。 Linux 没问题。
一种补救方法是在头文件中定义base
:
// a.h
const std::string base = "base";
// a.cpp
这是唯一的解决办法吗?或者有更好的方法吗?
不确定为什么标题提到了静态字符串初始化,并且这种行为可能取决于所使用的编译器,但是对于 vs2017,您应该在 b.cpp 文件中包含 a.h header。它对我有用。谢谢。
您可以使用 #pragma init_seg
指向 c++ 的指针默认位于 .CRT$XCU
部分(介于 .CRT$XCA
的 __xc_a
和 __xc_z
之间=17=] )
所以解决方案可以是下一个
// 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
将在 usage
[=25 之前初始化=]