MSVC 编译器/链接器何时合成标量/矢量删除析构函数



在使用现有项目时,对某些外部库进行了一些修改,在构建依赖于另一个动态链接库的库时,我遇到了以下问题:

错误 LNK2001:未解析的外部符号"公共:虚拟无效 * __cdecl Foo::'标量删除析构函数'(无符号整数(

错误 LNK2001:未解析的外部符号"public: Virtual void * __cdecl Foo::'vector delete destructor'(unsigned int(

如果我在有问题的.obj文件上运行dumpbin /symbols,我可以清楚地看到这些符号UNDEF.

对我来说有趣的是,没有其他未定义符号的抱怨,并且在目标文件符号转储中根本没有引用Foo析构函数。我可以在 StackOverflow 上找到的对这些合成函数的主要引用来自尚未定义其析构函数的人,但是我可以清楚地看到Foo::Foo从定义Foo的库中导出(通过在.lib上运行dumpbin /exports(。

这就引出了我问题的核心:Visual Studio(2015(何时选择合成这些功能,何时决定它们应该从另一个翻译单元链接?

我在VS2019的项目中遇到了相同的行为。但是在 VS2022(以及 GCC 和 Clang(中,相同的代码可以很好地编译/链接。

对我来说(并回答这个问题(,这是VS2019(及以下版本?(中的一个编译器错误,在我们的场景中(Foo有几个涉及大量"虚拟"的基类(,它是由

// Foo.h
~Foo() = default;   //< the culprit

但是,这两种解决方法中的任何一种都可以修复它:

  • 在标头中显式声明 DTor(foo.cpp中的定义没有帮助(:

    // Foo.h
    ~Foo() {};
    
  • 使用(至少一个(拒绝链接的 CPP 中缺少的运算符:

    // Foo.h
    ~Foo() = default;
    // Other.cpp
    void bar()
    {
    auto p = new Foo();
    delete p;
    }
    

最新更新