A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://en.cppreference.com/w/cpp/language/../utility/launder.html below:

std::launder - cppreference.com

template< class T >
constexpr T* launder( T* p ) noexcept;

(since C++17)

Devirtualization fence with respect to p. Returns a pointer to an object at the same address that p represents, while the object can be a new base class subobject whose most derived class is different from that of the original *p object.

Formally, given

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.

[edit] Notes

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:

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
[edit] Example
#include <cassert>
#include <cstddef>
#include <new>
 
struct Base
{
    virtual int transmogrify();
};
 
struct Derived : Base
{
    int transmogrify() override
    {
        new(this) Base;
        return 2;
    }
};
 
int Base::transmogrify()
{
    new(this) Derived;
    return 1;
}
 
static_assert(sizeof(Derived) == sizeof(Base));
 
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.
    Base base;
    int n = base.transmogrify();
    // int m = base.transmogrify(); // undefined behavior
    int m = std::launder(&base)->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.
    struct Y { int z; };
    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); // evokes [[maybe_unused]] effect
}
[edit] Defect reports

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 did not consider pointer
arithmetic from pointer-interconvertible object included LWG 3495 C++17 std::launder might make pointer to an inactive
member dereferenceable in constant expression forbidden

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4