Your code calls UB, but not for launder reasons. This is because p0[1].i is UB itself.
Yes, indeed ([Expr.Add] / 4):
When an expression that has an integral type is added or subtracted from the pointer, the result is the type of the operand of the pointer. If the expression P points to the element x [i] of the object of the array x with n elements, the expressions P + J and J + P (where J has the value j) indicate the (possibly hypothetical) element x [i + j] if 0 β€ i + j β€ n; otherwise, the behavior is undefined. Similarly, the expression P - J indicates a (possibly hypothetical) element x [i - j] if 0 β€ i - j β€ n; otherwise, the behavior is undefined.
An object that is not an element of an array is considered to be one array of elements; see 8.3.1. A pointer preceding the last element of an array x of n elements is considered equivalent to a pointer to a hypothetical element x [n] for this purpose; see 6.9.2.
[] , when applied to a pointer, means performing pointer arithmetic. And in the C ++ object model, pointer arithmetic can only be used for pointers to elements in an array of the specified type. You can always consider an object as an array of length 1, so you can get a one-way pointer for one object. Thus, p0 + 1 acts.
Access to the object stored at this address is invalid, although the pointer obtained using p0 + 1 . That is, p0[1].i is undefined behavior. Itβs like UB before washing it, as after.
Now consider another possibility:
X x[2]; x[1].~X(); //Destroy this object. new(x + 1) X; //Construct a new one.
So, we ask a few questions:
Is x[1] UB? I would say ... no, this is not UB. What for? Because x[1] not:
pointer pointing to the source object, a link related to the source object, or the name of the source object
x points to the array and the first element of this array, not the second element. Therefore, it does not indicate the source object. This is not a link, and it is not the name of this object.
Therefore, it does not fall under the restrictions specified in [basic.life] / 8. Therefore, x[1] should point to the newly constructed object.
Given that you do not need launder at all.
So, if you do it so legally, you do not need launder here.