Does destroying delete still require destructor being accessible?
Asked Answered
B

1

7

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?

Byproduct answered 8/9, 2020 at 15:48 Comment(2)
C++20 implementations are not yet complete, so you should check what your compilers claim to support before trying to rely on it.Feodora
@NicolBolas At least cppreference says these compilers all support it.Byproduct
R
4

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.

Recommit answered 8/9, 2020 at 16:16 Comment(3)
I've also seen the sentence, but I'm not sure if it's enough to judge that the standard doesn't require the accessibility to destructor. Indeed, if you make ~S() public, Clang/MSVC won't invoke the destructor, so aren't they technically conforming?Byproduct
@Byproduct This is where we get delete p; having to invoke a destructor, there's no other place where that would happen. The language doesn't typically require functions to be accessible even if not invoked. This is definitely a clang bug, I submitted 47474.Recommit
[expr.delete]p12: "Access and ambiguity control are done for both the deallocation function and the destructor (11.4.7, 11.12)."Ultimatum

© 2022 - 2024 — McMap. All rights reserved.