Explicit creation of objects with a trivial default constructor using placement-new in C++17

71 Views Asked by At

My understanding is that the rules about implicit creation of implicit-lifetime objects applies only to C++20 and newer. I'm stuck with C++17, so I wondered if I could fix this example code (so that it is not UB in C++17) by adding a placement-new expression that doesn't initialize the object, like this:

#include <cstdlib>
#include <new>

struct X { int a, b; };

// I believe writing to the fields of the returned object is UB in C++17, OK in C++20 and later.
X* make_uninitialized_x() {
    auto p = (X*)std::malloc(sizeof(X));
    return p;
}

// Is writing to the fields of the returned object OK in C++17 and earlier?
X* make_uninitialized_x_fixed_for_cpp17() {
    auto p = (X*)std::malloc(sizeof(X));
    new (p) X;  // This gets optimized away with -O1 flag
    return p;
}
1

There are 1 best solutions below

0
StableGeneous On BEST ANSWER

Answering my own question: According to the comments, either one of the fixed functions below would be OK in C++17 and earlier.

#include <cstdlib>
#include <new>

struct X { int a, b; };

X* make_uninitialized_x_fixed_v1() {
    auto p = (X*)std::malloc(sizeof(X));
    new (p) X;
    return std::launder(p);
}

X* make_uninitialized_x_fixed_v2() {
    auto p = (X*)std::malloc(sizeof(X));
    return new (p) X;
}