首页 > 解决方案 > 未定义的对clang中的析构函数的引用

问题描述

编译以下代码会给出“对 `A::~A() 的未定义引用”:

#include <cstdlib>
#include <memory>

template <typename T>
struct A {
        A() {}
        ~A() {}
};

struct Aggregate {
        using key_vector = A<char>;
        using value_vector = A<int>;

        value_vector vals;
        key_vector keys;
};

int
main()
{
        auto x = malloc(sizeof(Aggregate));
        new (x) Aggregate{};

        return 0;
}

问题出现在 clang 7.0 和 6.0 上(可能还有一些旧版本)。见:https ://godbolt.org/z/GNPk3V

在较新的 clang 版本和 gcc 上它工作正常。

这是预期的还是clang中的某种错误?

标签: c++linkercompiler-constructionclang

解决方案


这似乎是错误 28280,由https://reviews.llvm.org/D45898修复:

如果花括号初始化列表中的初始化程序是具有非平凡析构函数的 C++ 类,则将析构函数标记为已引用。这修复了 CodeGenFunction::destroyCXXObject 中的崩溃,当它尝试在堆栈展开路径上发出对析构函数的调用但类的 CXXRecordDecl 没有析构函数的 CXXDestructorDecl 时,会发生崩溃。

这个例子确实使用了一个花括号初始化列表,并在调用之前发出了析构函数调用_Unwind_Resume。析构函数不是微不足道的。将初始化更改为使用()而不是{}使错误消失,因为它不再使用花括号初始化列表进行初始化。我评论中的析构函数调用可能会导致析构函数被标记为引用。也许启用优化与使这仅出现在非平凡的析构函数中的事情相同。


推荐阅读