Is it OK not to call the destructor on placement new allocated objects?

The standard has a rule in section 3.8 [basic.life] that covers this:

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

Lots of experts are in agreement that “depends on the side effects produced by the destructor” is far too vague to be useful. Many interpret it as a tautology meaning “If the program has undefined behavior when the destructor side effects are not evaluated, then failing to call the destructor causes undefined behavior”. See Observable behavior and undefined behavior — What happens if I don’t call a destructor?

If your type has a trivial destructor (which appears to be the case in your example), then calling it (or failing to call it) has no effect whatsoever — calling a trivial destructor does not even end the life of the object.

The lifetime of an object o of type T ends when:

  • if T is a class type with a non-trivial destructor, the destructor call starts, or
  • the storage which the object occupies is released, or is reused by an object that is not nested within o.

That is, if T doesn’t have a non-trivial destructor, the only way to end the lifetime of object o is to release or reuse its storage.

Leave a Comment