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

Does destroying delete still require destructor being accessible?

C++20 引入了“破坏运算符删除”的概念,as described below:

delete-expressions does not execute the destructor for *p before placing a call to operator delete

因此,给定以下 struct S

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

private:
    ~S();
};

我希望下面的 delete 不会插入对析构函数的调用,而只是调用我们提供的 destroying operator delete

delete new S;

然而,GCC/Clang/MSVC 表现不同:DEMO

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

哪个是正确的?

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

来自[expr.delete]/6

If the value of the operand of the delete-expression is not a null pointer value and the selected deallocation function (see below) is not a destroying operator delete, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted.

只有在销毁delete的情况下才会调用析构函数。事实上,这就是 destroying delete 的全部意义所在——让 class 作者控制 how/when 来调用析构函数。因此,不要求析构函数可访问 - 调用它不取决于语言,而取决于用户。