std::launder
has a precondition that all bytes reachable from the would-be-returned pointer are reachable through the passed pointer.
My understanding is that this is meant to allow compiler optimizations, so that e.g.
struct A {
int a[2];
int b;
};
void f(int&);
int g() {
A a{{0,0},2};
f(a.a[0]);
return a.b;
}
can be optimized to always return 2
. (see Pointer interconvertibility vs having the same address and Can std::launder be used to convert an object pointer to its enclosing array pointer?)
Does this mean the reachability precondition should also apply to placement-new? Otherwise is there anything preventing me from writing f
as follows?:
void f(int& x) {
new(&x) A{{0,0},0};
}
The address of a.a[0]
is the same as that of a
and the new A
object is transparently replaceable with the old A
object, so that a.b
in g
should now be 0
.
return a.b;
ing
is going to be UB for accessing the member outside the object's lifetime. It wouldn't affect the optimization. – Forelegf
– Shoulder