c++standardsundefined-behaviorlifetimec++26

Do we really need std::start_lifetime_as if a well-defined alternative already exists?


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?


Solution

  • The differences between these two cases are:

    1. The second case cannot work with automatic objects, such as buf in the first case.
    2. The second case does not initialize the bytes, which is the entire point of the first example.