When to use std::launder?

82 Views Asked by At

I've read a few Q/A about std::launder (What is the purpose of std::launder?, Does this really break strict-aliasing rules?, std::launder reachability rules), but am still unclear whether I am using it correctly in my specific use-case. The following is what I am trying to achieve:

struct Base {
    ...
};

struct Derived : Base {
    ...
};

// Declare a buffer
alignas(std::max_align_t) char buffer[2000];

// Populate the buffer using placement-new
*reinterpret_cast<size_t*>(&buffer[0]) = sizeof(Derived);
Derived *d = new (&buffer[2 * sizeof(std::max_align_t)]) Derived();
*reinterpret_cast<Base**>(&buffer[sizeof(std::max_align_t)]) = static_cast<Base*>(d);

// Extract values from the buffer
size_t s = *reinterpret_cast<size_t*  >(&buffer[0]);
Base  *b = *reinterpret_cast<Base**   >(&buffer[sizeof(std::max_align_t)]);
       d = *reinterpret_cast<Derived**>(&buffer[sizeof(std::max_align_t) * 2]);

My inclination is that the following is the appropriate way to std::launder the above statements to ensure they all result in defined behavior per the standard:

// Populate the buffer using placement-new
*std::launder(reinterpret_cast<size_t*>(&buffer[0])) = sizeof(Derived);
Derived *d = new (&buffer[2 * sizeof(std::max_align_t)]) Derived();
*std::launder(reinterpret_cast<Base**>(&buffer[sizeof(std::max_align_t)])) = static_cast<Base*>(d);

// Extract values from the buffer
size_t s = *std::launder(reinterpret_cast<size_t*  >(&buffer[0]));
Base  *b = *std::launder(reinterpret_cast<Base**   >(&buffer[sizeof(std::max_align_t)]));
       d = *std::launder(reinterpret_cast<Derived**>(&buffer[sizeof(std::max_align_t) * 2]));

Is the above the appropriate usage of std::launder? Do I have to placement-new the size_t and Base* members prior to assigning to them? Do I have to std::launder the size_t and Base* members at all?

0

There are 0 best solutions below