【发布时间】:2020-03-21 08:42:07
【问题描述】:
我在头文件中有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。
这是在b.cpp 中向base 抛出的。所以我收集到这是静态初始化顺序的问题。但在我的生成文件中,我在 b.obj 之前列出了 a.obj,所以我不明白为什么会发生这种情况。
请注意,我只在 Windows 上收到此错误。 Linux 很好。
一种补救方法是在头文件中定义base:
// a.h
const std::string base = "base";
// a.cpp
这是唯一的解决方案吗?还是有更好的办法?
【问题讨论】:
-
考虑将
base放入返回局部静态变量的函数中,请参阅:blog.mbedded.ninja/programming/languages/c-plus-plus/… -
遗憾的是,这是 Windows 上经常出现的问题(尤其是使用 MSVC)。请不要使用非 POD 外部全局变量,因为它会导致很多问题(不仅在 Windows 上)。此外,请注意,如果这是一个编译时常量,则使用 C++20
constexpr字符串或 C++17constexpr std::string_view可能会有所帮助。
标签: c++ windows dll dynamic-linking static-initialization