Search code examples
c++destructordelete-operatorc++20

Does destroying delete still require destructor being accessible?


C++20 introduces the concept of a "destroying operator delete", as described below:

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

So, given the following struct S:

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

private:
    ~S();
};

I'd expect the delete below to not insert a call to destructor but just call destroying operator delete we provided

delete new S;

However, GCC/Clang/MSVC behave differently: DEMO

Only GCC doesn't try to access ~S(), others still require ~S() being accessible.

Which one is correct?


Solution

  • gcc is correct: ~S() need not be accessible.

    From [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.

    It's only in the case of not destroying delete that the destructor is invoked. Indeed, that's the whole point of destroying delete - to give the class author control of how/when to invoke the destructor. As such, there is no requirement that the destructor be accessible - it's not up to the language to invoke it, it's up to the user.