placement new and storage reuse
16:19 04 Mar 2025

In several location within the standard, storage reuse is mentioned, such as here: https://timsong-cpp.github.io/cppwp/n4861/basic.life#1.5.

But I cannot get a proper definition of what is a storage reuse vs what would be an incorrect object creation. I'll illustrate that with the following snippet:

#include 
#include 
#include 

int main() {
    std::byte storage[10000];
    std::int32_t *po0 = new (storage + 2 * sizeof(std::int32_t)) std::int32_t;
    // does this "reuse" po0 storage?
    std::int16_t *po1 = new (storage + 2 * sizeof(std::int32_t)) std::int16_t;
    // std::int64_t *po2 = new (storage + 2 * sizeof(std::int32_t)) std::int64_t;
    // std::int16_t *po3 =
    //     new (storage + 2 * sizeof(std::int32_t) + sizeof(std::int8_t))
    //         std::int16_t;
    // std::int32_t *po4 =
    //     new (storage + 2 * sizeof(std::int32_t) + sizeof(std::int32_t))
    //         std::int32_t;
    // std::int32_t *po5 =
    //     new (storage + 2 * sizeof(std::int32_t) - sizeof(std::int16_t))
    //         std::int32_t;
    // std::int64_t *po6 =
    //     new (storage + 2 * sizeof(std::int32_t) - sizeof(std::int16_t))
    //         std::int64_t;
}

LIVE

NB for simplicity sake, I didn't consider alignment issues but only where the new object creation is occurring (before the first object, at same location, inside the object) and how the new object is overlapping the first one.
NB I used integers for the example, but it can be any type.
NB consider that only one of the six objects *po1 to *po6 is created.

Which of these 6 object creation by placement new are valid and constitute a storage reuse, that will end *po0 lifetime?

Here is a graphical representation of the different scenarios:

po0 po0 po0 po0
po1 po1
po2 po2 po2 po2 po2 po2 po2 po2
po3 po3
po4 po4 po4 po4
po5 po5 po5 po5
po6 po6 po6 po6 po6 po6 po6 po6
c++ memory-management language-lawyer lifetime placement-new