内联映射初始化的动态atexit析构函数崩溃

dynamic atexit destructor crash for inline map initialization

本文关键字:atexit 析构函数 崩溃 动态 映射 初始化      更新时间:2023-10-16

我有一个通用的头文件,它将用于我的静态lib、dll和exe。静态库链接到我的exe和dll。Dll将由exe加载。对于其中一个要求,我想使用一个全局映射,它将在dll和exe中使用,但我不能,因为头中不允许初始化(得到多个重新定义错误(。所以我使用了C++17的内联特性。

在我的头文件中,我声明了这样一个映射。

enum class eCategory
{
eInvalid = 0,
eCategory1 = 1,
eCategory2,
eCategory3,
eCategory4
};

inline std::map<eCategory, std::string> testCategoryMap{
{ eCategory::eCategory1, "Category1" },
{ eCategory::eCategory2, "Category2"},
{ eCategory::eCategory3, "Category3"},
{ eCategory::eCategory4, "Category4" },
{ eCategory::eInvalid, "Invalid" }
};

当我试图执行我的exe时,我在出口析构函数崩溃时得到了动态。此链接https://stackoverflow.com/questions/1952467/what-does-dynamic-in-dynamic-atexit-destructor-mean建议我使用atexit((,但不确定如何实现。

有人能帮我解决这个问题吗。

注意:我刚刚用static替换了inline,并将其添加到命名空间中,它运行良好。使用静电有什么害处吗?

但我刚刚用static替换了inline,它就开始工作了。

使用static会绕过应用程序范围的一定义规则(ODR(。ODR变成了特定于编译单元的。这意味着您将在应用程序中分布多个testCategoryMap实例,它们都不会相互干扰。

仅使用inline关键字意味着应用程序范围的One Definition Rule确实适用。让多个编译单元包含相同的头文件是ODR冲突:不需要诊断。当一个应用程序有多个包含该标头的编译单元时,无论该应用程序是否构建,都是一个未定义的行为抛出;如果它确实构建了,无论应用程序是否在某个时刻崩溃,都是未定义的行为抛出。