Search code examples
c++language-lawyerc++20c++23

Does the C++ standard forbid reusing storage without destroying?


Which parts of a modern C++ standard (C++20 or C++23 are fine) say whether it's okay to reuse an object's storage without running its destructor using placement new?

alignas(T) std::byte storage[sizeof(T)];
T* p = new (storage) T(...);
p = new (storage) T(...)
p->~T();

If it's not allowed in general, are there any conditions this is allowed, e.g. if T has a trivial destructor?


Solution

  • The C++20 standard says explicitly in [basic.life]/5 that it's okay to reuse storage without calling the destructor:

    For an object of a class type, 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 is not used to release the storage, the destructor is not implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

    For types with a trivial destructor this seems totally innocuous: their destructors by definition have no side effects, so the program can't depend on them.

    For an arbitrary type it doesn't seem like this is a particularly good idea, but I can't find any language that says it's UB independent of what the rest of the program does.