Why operator delete overloading doesn't call infinite recursive call on calling delete

Viewed 95

Calling local overload of operator new causes stack overflow due to infinite recursive calls but when same happens with local overload of operator delete, why global operator delete is called (hence avoiding the stack crash). Simple code goes like this-

class A {
public:
    void * operator new(size_t n) {
        //return new A();calls local overloaded version and stack overflows
        return ::new A();
    }

    void operator delete(void* p)
    {
        delete(p);//why its calling global version?
        //::delete(p);//calls global version
    }
};

int main()
{
    A *a = new A();
    delete(a); 
}

My question is why delete from overloaded operator delete doesn't call itself but the global operator delete?

1 Answers

I'm trying to summarize my comments into the answer.

delete is a keyword, not a function or operator. So it does not behave like functions.

When you write delete p, compilers does not perform lookup for overloads like for functions. When a compiler meets the expressions delete p it performs lookup between available overloads operator delete for the type of the pointer p. If p is a pointer to a class, and a class specific overload exists then p->operator delete(some_ptr) is called. Otherwise a compiler performs lookup between scoped void operator delete(void*).

Returning to you example.

A *a = new A();
delete(a);  // a is pointer to class, calls a->operator delete(a);

void A::operator delete(void* p) {
  delete(p);  // p is pointer to void, calls ::operator delete(p);
}

If you call operator delete(a);, it is like a function call, and A::operator delete(void*); is not called.

If you call operator delete(p); from the inside of A::operator delete(void* p);, you get the infinite recursion.

If you call delete static_cast<A*>(p); from the inside of A::operator delete(void* p);, you get the infinite recursion again.

Related