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;
}
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;
}