Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 705
Jamboree Avatar asked Sep 08 '20 15:09

Jamboree


People also ask

Does delete always call destructor?

The answer is yes. Destructor for each object is called. On a related note, you should try to avoid using delete whenever possible.

Does delete call destructor in C++?

When delete is used to deallocate memory for a C++ class object, the object's destructor is called before the object's memory is deallocated (if the object has a destructor). If the operand to the delete operator is a modifiable l-value, its value is undefined after the object is deleted.

In what way destructor is different from delete?

So delete is for managing the dynamic memory, but the destructor is a method of the class itself, which is always called when the object is getting freed from the memory (stack or heap).

Does the destructor remove memory allocated to an object?

A destructor only destroys and cleans up the object. It does not deallocate the memory.


1 Answers

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.

like image 96
Barry Avatar answered Sep 19 '22 12:09

Barry