销毁 delete 是否仍然需要可以访问析构函数?

Jam*_*ree 7 c++ destructor delete-operator c++20

C++20 引入了“销毁运算符删除”的概念,如下所述:

在调用 operator delete 之前,delete-expressions 不会执行 *p 的析构函数

因此,鉴于以下情况struct S:

struct S {
    void operator delete(S* p, std::destroying_delete_t);

private:
    ~S();
};
Run Code Online (Sandbox Code Playgroud)

我希望delete下面不会插入对析构函数的调用,而只是调用我们提供的销毁操作符 delete

delete new S;
Run Code Online (Sandbox Code Playgroud)

但是,GCC/Clang/MSVC 的行为有所不同:DEMO

只有 GCC 不会尝试访问~S(),其他人仍然需要~S()可访问。

哪一个是正确的?

Bar*_*rry 4

gcc 是正确的:~S()不需要可访问。

来自[expr.delete]/6:

如果删除表达式的操作数的值不是空指针值,并且所选的释放函数(见下文)不是破坏运算符删除,则删除表达式将调用该对象或对象的析构函数(如果有)正在删除的数组的元素。

只有在不破坏delete的情况下才会调用析构函数。事实上,这就是销毁删除的全部意义 - 让类作者控制如何/何时调用析构函数。因此,不要求析构函数可访问 - 调用它不取决于语言,而取决于用户。