Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::launder

      From cppreference.com
      <cpp‎ |utility
       
       
      Utilities library
       
      Memory management library
      (exposition only*)
      Allocators
      Uninitialized memory algorithms
      Constrained uninitialized memory algorithms
      Memory resources
      Uninitialized storage(until C++20)
      (until C++20*)
      (until C++20*)
      Garbage collector support(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
      (C++11)(until C++23)
       
       
      Defined in header<new>
      template<class T>
      constexpr T* launder( T* p)noexcept;
      (since C++17)

      Devirtualization fence with respect top. Returns a pointer to an object at the same address thatp 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

      • the pointerp represents the addressA of a byte in memory
      • an objectx is located at the addressA
      • x is within itslifetime
      • the type ofx is the same asT, ignoring cv-qualifiers at every level
      • every byte that would be reachable through the result is reachable through p (bytes are reachable through a pointer that points to an objecty if those bytes are within the storage of an objectz that ispointer-interconvertible withy, or within the immediately enclosing array of whichz is an element).

      Thenstd::launder(p) returns a value of typeT* that points to the objectx. Otherwise, the behavior is undefined.

      The program is ill-formed ifT is a function type or (possibly cv-qualified)void.

      std::launder may be used in acore 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 ofstd::launder include:

      • Obtaining a pointer to an object created in the storage of an existing object of the same type, where pointers to the old object cannot bereused (for instance, because either object is a base class subobject);
      • Obtaining a pointer to an object created by placementnew from a pointer to an object providing storage for that object.

      Thereachability restriction ensures thatstd::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 paddingauto p3= std::launder(reinterpret_cast<int(*)[10]>(&x3.a[0]));// OKauto 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

      Run this code
      #include <cassert>#include <cstddef>#include <new> struct Base{virtualint transmogrify();}; struct Derived: Base{int transmogrify() override{        new(this) Base;return2;}}; int Base::transmogrify(){    new(this) Derived;return1;} 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 behaviorint m= std::launder(&base)->transmogrify();// OKassert(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};constint 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 objectconstint g= q->z;// OKconstint 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.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 2859C++17definition ofreachable did not consider pointer
      arithmetic from pointer-interconvertible object
      included
      LWG 3495C++17std::launder might make pointer to an inactive
      member dereferenceable in constant expression
      forbidden
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/utility/launder&oldid=177326"

      [8]ページ先頭

      ©2009-2025 Movatter.jp