2

Suppose I have a class foo with a function release that calls delete this:

struct foo
{
    std::int32_t release() const
    {
        delete this;
        return 0;
    }
};
  1. Why can I even call delete this given that the function is const?

  2. Is the behaviour on returning 0 defined? Doesn't the function "sort-of-die" after the delete?

An answer referencing the standard (so I can put a fancy comment in my code) would be much appreciated.

P45 Imminent
  • 8,319
  • 4
  • 35
  • 78
  • 2
    Morning Slodge: for once I can't answer your question. I think it's safe since I wrote the code along time ago and I still enjoy full-time employment! 1. deletion is not really modifying an object, it's blasting an object out of existence, 2. think of member functions as being no more than statics with an extra (although hidden) `this` parameter. As long as you don't refer to `this` after deleting the object, you'll be fine. PS it's *our* code. – Bathsheba Oct 14 '15 at 07:41
  • 1
    Here's an entry on this in the [C++ FAQ](https://isocpp.org/wiki/faq/freestore-mgmt#delete-this). – TartanLlama Oct 14 '15 at 07:42
  • It's used in COM-style reference counting. – P45 Imminent Oct 14 '15 at 07:42
  • see also [Is it safe to 'delete this'?](http://stackoverflow.com/questions/550189/is-it-safe-to-delete-this) – TheOperator Oct 14 '15 at 07:44
  • You can `delete` a pointer to const, because const objects can be destroyed like any other object. Stack objects can be destroyed even though they're const, and so can heap objects. Otherwise you'd never be able to free memory for: `using cfoo = const foo; auto* p = new cfoo();` – Jonathan Wakely Oct 14 '15 at 07:45
  • 1
    qualifying the function as const is a mistake. You can pass the object by const reference and anybody can release. I dont want to debug this code. – UmNyobe Oct 14 '15 at 07:45
  • It's how ATL implements IUnknown, so I guess the cat just copied that pattern. – P45 Imminent Oct 14 '15 at 07:47

2 Answers2

1

Why can I even call delete this given that the function is const

Because delete doesn't necessarily modify the deleted pointer.

Is the behaviour on returning 0 defined? Doesn't the function "sort-of-die" after the delete?

Why would it? The logic isn't removed from the program. The functionality stays in memory for next objects to use it. It's only this pointer that gets invalidated.

There's an SO answer that points to The ISO C++ FAQ which has an entry on that, excerpts of which:

  1. You must be absolutely 100% positively sure that the rest of your member function (after the delete this line) doesn’t touch any piece of this object (including calling any other member functions or touching any data members). This includes code that will run in destructors for any objects allocated on the stack that are still alive.
  2. You must be absolutely 100% positively sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with nullptr, print it, cast it, do anything with it.

Since your code abides those rules, again, it's fine.

Community
  • 1
  • 1
Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • 1
    "It takes the pointer by value (void*), to which any T* can be converted." -- This is not true, the `delete` operator works on the *typed* pointer, otherwise it couldn't invoke the destructor. What you are referring to is the function `operator delete`. – TheOperator Oct 14 '15 at 07:46
1
  1. Why can I even call delete this given that the function is const?

From the standard, 5.3.5$2 Delete [expr.delete]

[ Note: a pointer to a const type can be the operand of a delete-expression; it is not necessary to cast away the constness (5.2.11) of the pointer expression before it is used as the operand of the delete-expression. —end note ]

and

  1. Is the behaviour on returning 0 defined?

I think it's safe. delete this; will call the destructor and free the memory hold by the object (including the member variables and base class subobject). After that, if you don't derefrence this, or access any member variables, it'll be safe.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405