17 Language support library [language.support]

17.6 Dynamic memory management [support.dynamic]

17.6.4 Pointer optimization barrier [ptr.launder]

template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept;
Mandates: !is_­function_­v<T> && !is_­void_­v<T> is true.
Expects: p represents the address A of a byte in memory.
An object X that is within its lifetime and whose type is similar to T is located at the address A.
All bytes of storage that would be reachable through the result are reachable through p (see below).
Returns: A value of type T * that points to X.
Remarks: An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression.
A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element.
If a new object is created in storage occupied by an existing object of the same type, a pointer to the original object can be used to refer to the new object unless the type contains const or reference members; in the latter cases, this function can be used to obtain a usable pointer to the new object.
— end note
struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5};                       // p does not point to new object ([basic.life]) because X​::​n is const
const int b = p->n;                 // undefined behavior
const int c = std::launder(p)->n;   // OK
— end example