静态字符串初始化顺序问题

问题描述 投票:0回答:2

我在头文件中有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

这是唯一的解决方案吗?还是有更好的方法?

c++ windows dll dynamic-linking static-initialization
2个回答
0
投票

[不确定标题为何提到静态字符串初始化,并且此行为可能取决于所使用的编译器,但对于vs2017,应在b.cpp文件中包含a.h标头。它为我工作。谢谢。


0
投票

您可以通过#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之前被初始化
© www.soinside.com 2019 - 2024. All rights reserved.