Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

operator new() behaves differently when operator delete() is deleted depending on the existence of the default constructor

Creating a new object of class C with operator new() gives an error here:

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

with C2280: 'void C::operator delete(void *)': function was explicitly deleted

But when I replace C() {} with C() = default; or remove the line so that compiler inserts a default constructor(which I believe has the same effect with = default), the code will compile and run.

What are the differences between compiler-generated default constructor and user-defined default constructor that make this happen?

I got some hint in this posting, but class C here(without user-provided constructor) isn't trivial since the destructor is virtual, right?

Compiled with latest Visual Studio, c++17.

like image 612
yeshjho Avatar asked Feb 12 '20 09:02

yeshjho


People also ask

What is the difference between new and delete operator in C++?

The main difference between new and delete operator in C++ is that new is used to allocate memory for an object or an array while, delete is used to deallocate the memory allocated using the new operator. There are two types of memory as static and dynamic memory.

What is the purpose of the delete operator?

The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned. However, it is important to consider the following scenarios: If the property which you are trying to delete does not exist, delete will not have any effect and will return true .

What is the purpose of the delete operator C++?

delete keyword in C++ Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. New operator is used for dynamic memory allocation which puts variables on heap memory. Which means Delete operator deallocates memory from heap.

Which operator is used to allocate an object dynamically of a class in C++? *?

C++ supports dynamic allocation and deallocation of objects using the new and delete operators. These operators allocate memory for objects from a pool called the free store (also known as the heap).


1 Answers

What are the differences between compiler-generated default constructor and user-defined default constructor that make this happen?

new expression invokes the corresponding operator new and then calls the constructor. If the constructor throws an exception new expression must undo the effect of operator new (to avoid leaking memory) by calling the corresponding operator delete. If the latter is deleted new expression cannot call it which results in the compiler error: use of deleted function 'static void C::operator delete(void*)'.

A noexcept constructor cannot possibly throw an exception, hence, the corresponding operator delete is not necessary as it won't be called by a new expression. A default constructor of a trivial class is also a noexcept constructor. The presence of a virtual destructor requires operator delete to be non-deleted because the special scalar deleting destructor (an implementation detail to enable delete expression through the base class pointer) invokes operator delete.

It seems to be unspecified by the C++ standard whether the compiler must require operator delete to be non-deleted even if it cannot possibly be called by new expression. gcc, however, doesn't seem to be invoking the corresponding operator delete in new expression at all if it is deleted (posted a bug report).

like image 120
Maxim Egorushkin Avatar answered Oct 13 '22 05:10

Maxim Egorushkin