diff --git a/public/docs/cpp/utility/launder.html b/public/docs/cpp/utility/launder.html deleted file mode 100644 index 3b838a9e..00000000 --- a/public/docs/cpp/utility/launder.html +++ /dev/null @@ -1,91 +0,0 @@ -
Defined in header <new> | ||
---|---|---|
template <class T> -constexpr T* launder(T* p) noexcept;- | (since C++17) (until C++20) | |
template <class T> -[[nodiscard]] constexpr T* launder(T* p) noexcept;- | (since C++20) |
Obtains a pointer to the object located at the address represented by p
.
Formally, given
-p
represents the address A
of a byte in memory X
is located at the address A
X
is within its lifetime X
is the same as T
, ignoring cv-qualifiers at every level Y
if those bytes are within the storage of an object Z
that is pointer-interconvertible with Y
, or within the immediately enclosing array of which Z
is an element). Then std::launder(p)
returns a value of type T*
that points to the object X
. Otherwise, the behavior is undefined.
The program is ill-formed if T
is a function type or (possibly cv-qualified) void
.
std::launder
may be used in a core constant expression if and only if the (converted) value of its argument may be used in place of the function invocation. In other words, std::launder
does not relax restrictions in constant evaluation.
std::launder
has no effect on its argument. Its return value must be used to access the object. Thus, it's always an error to discard the return value.
Typical uses of std::launder
include:
new
from a pointer to an object providing storage for that object. The reachability restriction ensures that std::launder
cannot be used to access bytes not accessible through the original pointer, thereby interfering with the compiler's escape analysis.
int x[10]; -auto p = std::launder(reinterpret_cast<int(*)[10]>(&x[0])); // OK - -int x2[2][10]; -auto p2 = std::launder(reinterpret_cast<int(*)[10]>(&x2[0][0])); -// Undefined behavior: x2[1] would be reachable through the resulting pointer to x2[0] -// but is not reachable from the source - -struct X { int a[10]; } x3, x4[2]; // standard layout; assume no padding -auto p3 = std::launder(reinterpret_cast<int(*)[10]>(&x3.a[0])); // OK -auto p4 = std::launder(reinterpret_cast<int(*)[10]>(&x4[0].a[0])); -// Undefined behavior: x4[1] would be reachable through the resulting pointer to x4[0].a -// (which is pointer-interconvertible with x4[0]) but is not reachable from the source - -struct Y { int a[10]; double y; } x5; -auto p5 = std::launder(reinterpret_cast<int(*)[10]>(&x5.a[0])); -// Undefined behavior: x5.y would be reachable through the resulting pointer to x5.a -// but is not reachable from the source
#include <new> -#include <cstddef> -#include <cassert> - -struct Y { - int z; -}; - -struct A { - virtual int transmogrify(); -}; - -struct B : A { - int transmogrify() override { new(this) A; return 2; } -}; - -int A::transmogrify() { new(this) B; return 1; } - -static_assert(sizeof(B) == sizeof(A)); - -int main() -{ - // Case 1: the new object failed to be transparently replaceable because it is a - // base subobject but the old object is a complete object. - A i; - int n = i.transmogrify(); - // int m = i.transmogrify(); // undefined behavior - int m = std::launder(&i)->transmogrify(); // OK - assert(m + n == 3); - - // Case 2: access to a new object whose storage is provided by a byte array through - // a pointer to the array. - alignas(Y) std::byte s[sizeof(Y)]; - Y* q = new(&s) Y{2}; - const int f = reinterpret_cast<Y*>(&s)->z; // Class member access is undefined behavior: - // reinterpret_cast<Y*>(&s) has value - // "pointer to s" and does not - // point to a Y object - const int g = q->z; // OK - const int h = std::launder(reinterpret_cast<Y*>(&s))->z; // OK - - [f, g, h] {}; // suppresses "unused-variable" warnings; see also [[maybe_unused]]. -}
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
-DR | Applied to | Behavior as published | Correct behavior | -
---|---|---|---|
LWG 2859 | C++17 | definition of reachable didn't consider pointer-arithmetic from pointer-interconvertible object | included | -
LWG 3495 | C++17 | launder might make pointer to an inactive member dereferenceable in constant expression | forbidden | -
- © cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
- https://en.cppreference.com/w/cpp/utility/launder
-