Why there is no placement delete expression in C++?
Asked Answered
S

4

39

Why C++ hasn't placement delete that directly corresponds to the placement new, i.e. calls the destructor and calls appropriate placement delete operator?

For example:

MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);

//proposed technique
delete(arena) p;
Stopcock answered 2/5, 2011 at 12:42 Comment(6)
doesn't delete automatically call destructor?Cavalier
For objects created with placement new no, it doesn'tForeground
Hi, I know it's been a while but this is a very good question and the answers were all way off the mark. This kind of thing shouldn't be about apologizing for shortcomings or rationalizing why the standard committee must not have wanted something just because it isn't there.Brann
related question: https://mcmap.net/q/272660/-placement-new-and-deleteFerrante
Stroustrup's C++ FAQ: Is there a "placement delete"?Lazaro
@Brann I agree this is a good question, I'm just guessing why speculative answers sometimes get refused and sometimes accepted, seems there's something like a Elite or a Mafia in there sometimes >)Salo
B
26

operator delete is unique in being a non-member or static member function that is dynamically dispatched. A type with a virtual destructor performs the call to its own delete from the most derived destructor.

struct abc {
    virtual ~abc() = 0;
};

struct d : abc {
    operator delete() { std::cout << "goodbye\n"; }
};

int main() {
    abc *p = new d;
    delete p;
}

(Run this example.)

For this to work with placement delete, the destructor would have to somehow pass the additional arguments to operator delete.

  • Solution 1: Pass the arguments through the virtual function. This requires a separate virtual destructor for every static member and global operator delete overload with different arguments.
  • Solution 2: Let the virtual destructor return a function pointer to the caller specifying what operator delete should be called. But if the destructor does lookup, this hits the same problem of requiring multiple virtual function definitions as #1. Some kind of abstract overload set would have to be created, which the caller would resolve.

You have a perfectly good point, and it would be a nice addition to the language. Retrofitting it into the existing semantics of delete is probably even possible, in theory. But most of the time we don't use the full functionality of delete and it suffices to use a pseudo-destructor call followed by something like arena.release(p).

Brann answered 2/1, 2013 at 9:9 Comment(2)
Interesting analysis, but still it is unclear to me why an hypothetical e.g. delete (args...) pointer; could not be simply resolved to e.g. pointer->~T(); operator delete(pointer, args...); (that is, the deleter function would not be called from the destructor directly, as I presume you suggest, but instead a call to the deleter would be introduced by the compiler just after the destructor call).Roee
@Alek For a polymorphic class, pointer is not what should be passed to operator delete. Instead it needs a derived_pointer. The problem is solvable, but only with a bit of complexity.Brann
T
8

Probably because there was syntax for explicitly calling a destructor without deallocation (exactly as in your question), but no syntax for explicit construction in raw memory?

Terzetto answered 2/5, 2011 at 12:48 Comment(1)
Explicit construction in raw memory is exactly what placement new is. (The memory may also obtained from something like an arena object.) But this answer doesn't draw any actual connection between construction and destruction; the point isn't clear.Brann
B
8

Actually there is a placement delete which is called by the implementation for an object that was "allocated" using placement new if the constructor threw an exception.

From Wikipedia.

The placement delete functions are called from placement new expressions. In particular, they are called if the constructor of the object throws an exception. In such a circumstance, in order to ensure that the program does not incur a memory leak, the placement delete functions are called.

Bumpy answered 9/7, 2012 at 13:55 Comment(1)
Despite the title, I think the question is about the calling convention of the placement delete compared to the calling convention of placement new, not the existence of placement delete.Reputation
F
2

The whole point of placement new is to separate object creation from its memory management. So it makes no sense to tie it back during object destruction.
If memory for your objects is from heap and you want same lifetime for objects and their memory just use operator new and operator delete, maybe overriding them if you want any special behavior.
Placement new is good for example in vector, which keeps a large chunk of raw memory and creates and destroys object inside of it, but without releasing memory.

Foreground answered 2/5, 2011 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.