Consider the code example excerpted from cppref:
#include <complex>
#include <iostream>
#include <memory>
int main() {
alignas(std::complex<float>) unsigned char buf[sizeof(std::complex<float>)] {
0xcd, 0xcc, 0xcc, 0x3d, 0xcd, 0xcc, 0x4c, 0x3e
};
auto d1 = *reinterpret_cast<std::complex<float>*>(buf);
std::cout << d1; // UB: violating the strict aliasing rule.
auto d2 = *std::start_lifetime_as<std::complex<float>>(buf);
std::cout << d2; // OK
}
The code above shows why we need std::start_lifetime_as
; however, I think the following code shows an alternative way:
int main() {
struct A { int n; };
auto buf = std::aligned_alloc(alignof(A), 1024);
// An object of A is implicity created here since C++20, conceptually.
receive_object_of_A_from_network(buf);
auto pa = static_cast<A*>(buf); // casting void* to A* is ok.
std::cout << pa->n; // well-defined since C++20.
pa->~A();
std::free(buf);
}
Do we really need std::start_lifetime_as
if an alternative already exists?
The differences between these two cases are:
buf
in the first case.