Delete public/docs directory

pull/1789/head^2
AgustinAl 3 years ago committed by GitHub
parent 67e722e958
commit 4aaf2ae516
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,91 +0,0 @@
<h1 id="firstHeading" class="firstHeading">std::launder</h1> <table class="t-dcl-begin"> <tr class="t-dsc-header"> <th> Defined in header <code><a href="../header/new" title="cpp/header/new">&lt;new&gt;</a></code> </th> <th> </th> <th> </th> </tr> <tr class="t-dcl t-since-cxx17 t-until-cxx20"> <td> <pre data-language="cpp">template &lt;class T&gt;
constexpr T* launder(T* p) noexcept;</pre>
</td> <td class="t-dcl-nopad"> </td> <td> <span class="t-mark-rev t-since-cxx17">(since C++17)</span> <br><span class="t-mark-rev t-until-cxx20">(until C++20)</span> </td> </tr> <tr class="t-dcl t-since-cxx20"> <td> <pre data-language="cpp">template &lt;class T&gt;
[[nodiscard]] constexpr T* launder(T* p) noexcept;</pre>
</td> <td class="t-dcl-nopad"> </td> <td> <span class="t-mark-rev t-since-cxx20">(since C++20)</span> </td> </tr> </table> <p>Obtains a pointer to the object located at the address represented by <code>p</code>.</p>
<p>Formally, given</p>
<ul>
<li> the pointer <code>p</code> represents the address <code>A</code> of a byte in memory </li>
<li> an object <code>X</code> is located at the address <code>A</code> </li>
<li> <code>X</code> is within its <a href="../language/lifetime" title="cpp/language/lifetime">lifetime</a> </li>
<li> the type of <code>X</code> is the same as <code>T</code>, ignoring cv-qualifiers at every level </li>
<li> every byte that would be reachable through the result is reachable through p (bytes are reachable through a pointer that points to an object <code>Y</code> if those bytes are within the storage of an object <code>Z</code> that is <a href="../language/static_cast#pointer-interconvertible" title="cpp/language/static cast">pointer-interconvertible</a> with <code>Y</code>, or within the immediately enclosing array of which <code>Z</code> is an element). </li>
</ul> <p>Then <code>std::launder(p)</code> returns a value of type <code>T*</code> that points to the object <code>X</code>. Otherwise, the behavior is undefined.</p>
<p>The program is ill-formed if <code>T</code> is a function type or (possibly cv-qualified) <code>void</code>.</p>
<p><code>std::launder</code> may be used in a <a href="../language/constant_expression" title="cpp/language/constant expression">core constant expression</a> if and only if the (converted) value of its argument may be used in place of the function invocation. In other words, <code>std::launder</code> does not relax restrictions in constant evaluation.</p>
<h3 id="Notes"> Notes</h3> <p><code>std::launder</code> 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.</p>
<p>Typical uses of <code>std::launder</code> include:</p>
<ul>
<li> 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 be <a href="../language/lifetime#Storage_reuse" title="cpp/language/lifetime">reused</a> (for instance, because either object is a base class subobject); </li>
<li> Obtaining a pointer to an object created by placement <code>new</code> from a pointer to an object providing storage for that object. </li>
</ul> <p>The <i>reachability</i> restriction ensures that <code>std::launder</code> cannot be used to access bytes not accessible through the original pointer, thereby interfering with the compiler's escape analysis.</p>
<div class="cpp source-cpp"><pre data-language="cpp">int x[10];
auto p = std::launder(reinterpret_cast&lt;int(*)[10]&gt;(&amp;x[0])); // OK
int x2[2][10];
auto p2 = std::launder(reinterpret_cast&lt;int(*)[10]&gt;(&amp;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&lt;int(*)[10]&gt;(&amp;x3.a[0])); // OK
auto p4 = std::launder(reinterpret_cast&lt;int(*)[10]&gt;(&amp;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&lt;int(*)[10]&gt;(&amp;x5.a[0]));
// Undefined behavior: x5.y would be reachable through the resulting pointer to x5.a
// but is not reachable from the source</pre></div> <h3 id="Example"> Example</h3> <div class="t-example"> <div class="cpp source-cpp"><pre data-language="cpp">#include &lt;new&gt;
#include &lt;cstddef&gt;
#include &lt;cassert&gt;
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(&amp;i)-&gt;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(&amp;s) Y{2};
const int f = reinterpret_cast&lt;Y*&gt;(&amp;s)-&gt;z; // Class member access is undefined behavior:
// reinterpret_cast&lt;Y*&gt;(&amp;s) has value
// "pointer to s" and does not
// point to a Y object
const int g = q-&gt;z; // OK
const int h = std::launder(reinterpret_cast&lt;Y*&gt;(&amp;s))-&gt;z; // OK
[f, g, h] {}; // suppresses "unused-variable" warnings; see also [[maybe_unused]].
}</pre></div> </div> <h3 id="Defect_reports"> Defect reports </h3> <p>The following behavior-changing defect reports were applied retroactively to previously published C++ standards.</p>
<table class="dsctable"> <tr> <th> DR </th> <th> Applied to </th> <th> Behavior as published </th> <th> Correct behavior </th>
</tr> <tr> <td> <a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2859">LWG 2859</a> </td> <td> C++17 </td> <td> definition of <i>reachable</i> didn't consider pointer-arithmetic from pointer-interconvertible object </td> <td> included </td>
</tr> <tr> <td> <a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue3495">LWG 3495</a> </td> <td> C++17 </td> <td> <code>launder</code> might make pointer to an inactive member dereferenceable in constant expression </td> <td> forbidden </td>
</tr>
</table> <div class="_attribution">
<p class="_attribution-p">
&copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
<a href="https://en.cppreference.com/w/cpp/utility/launder" class="_attribution-link">https://en.cppreference.com/w/cpp/utility/launder</a>
</p>
</div>
Loading…
Cancel
Save