70 lines
2.6 KiB
Markdown
70 lines
2.6 KiB
Markdown
[ptr.launder]
|
||
|
||
# 17 Language support library [[support]](./#support)
|
||
|
||
## 17.6 Dynamic memory management [[support.dynamic]](support.dynamic#ptr.launder)
|
||
|
||
### 17.6.5 Pointer optimization barrier [ptr.launder]
|
||
|
||
[ð](#lib:launder)
|
||
|
||
`template<class T> constexpr T* launder(T* p) noexcept;
|
||
`
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3160)
|
||
|
||
*Mandates*: !is_function_v<T> && !is_void_v<T> is true[.](#1.sentence-1)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3164)
|
||
|
||
*Preconditions*: p represents the address *A* of a byte in memory[.](#2.sentence-1)
|
||
|
||
An object *X* that is within its [lifetime](basic.life#def:lifetime "6.8.4 Lifetime [basic.life]") and whose type is [similar](conv.qual#def:similar_types "7.3.6 Qualification conversions [conv.qual]") to T is located at the address *A*[.](#2.sentence-2)
|
||
|
||
All bytes of storage that would be
|
||
reachable through ([[basic.compound]](basic.compound "6.9.4 Compound types")) the result
|
||
are reachable through p[.](#2.sentence-3)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3174)
|
||
|
||
*Returns*: A value of type T* that points to *X*[.](#3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3178)
|
||
|
||
*Remarks*: An invocation of this function
|
||
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[.](#4.sentence-1)
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3185)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
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 its complete object is a const object or it is a base class subobject;
|
||
in the latter cases,
|
||
this function can be used to obtain a usable pointer to the new object[.](#5.sentence-1)
|
||
|
||
See [[basic.life]](basic.life "6.8.4 Lifetime")[.](#5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3197)
|
||
|
||
[*Example [1](#example-1)*: struct X { int n; };const X *p = new const X{3};const int a = p->n;new (const_cast<X*>(p)) const X{5}; // p does not point to new object ([[basic.life]](basic.life "6.8.4 Lifetime")) because its type is constconst int b = p->n; // undefined behaviorconst int c = std::launder(p)->n; // OK â *end example*]
|