Difference between revisions of "cpp/memory/start lifetime as"
From cppreference.com
m (minor fix) |
m (typo fix) |
||
Line 55: | Line 55: | ||
{{par begin}} | {{par begin}} | ||
{{par | p | possible cv-qualified {{c|void}} pointer, denotes the address of the region consisting objects}} | {{par | p | possible cv-qualified {{c|void}} pointer, denotes the address of the region consisting objects}} | ||
− | {{par | n | {{c|std::size_t}}, denotes the size of the object array to | + | {{par | n | {{c|std::size_t}}, denotes the size of the object array to be created}} |
{{par end}} | {{par end}} | ||
Revision as of 05:14, 22 June 2023
Defined in header <memory>
|
||
start_lifetime_as |
||
template<class T> T* start_lifetime_as(void* p) noexcept; |
(1) | (since C++23) |
template<class T> const T* start_lifetime_as(const void* p) noexcept; |
(2) | (since C++23) |
template<class T> volatile T* start_lifetime_as(volatile void* p) noexcept; |
(3) | (since C++23) |
template<class T> const volatile T* start_lifetime_as(const volatile void* p) noexcept; |
(4) | (since C++23) |
start_lifetime_as_array |
||
template<class T> T* start_lifetime_as_array(void* p, std::size_t n) noexcept; |
(5) | (since C++23) |
template<class T> const T* start_lifetime_as_array(const void* p, std::size_t n) noexcept; |
(6) | (since C++23) |
template<class T> volatile T* start_lifetime_as_array(volatile void* p, std::size_t n) noexcept; |
(7) | (since C++23) |
template<class T> const volatile T* start_lifetime_as_array(const volatile void* p, std::size_t n) noexcept; |
(8) | (since C++23) |
1-4) Implicity creates a complete object of type
T
whose address is p
and objects nested within it. The value of each created object o
of TriviallyCopyable type U
is determined in the same manner as for a call to std::bit_cast<U>(E) except the storage is not really accessed, where E
is the lvalue of type U
denoting o
. Otherwise the value of such crated objects are unspecified.
-
T
shall be an ImplicitLifetimeType and shall not an incomplete type, otherwise the program is ill-formed. - The behavior is undefined if:
-
[
p,
(char*)p + sizeof(T))
does not denote a region of allocated storage that is a subset of the region of storage reachable throughp
, or - the region is not suitably aligned for the
T
.
-
- Note that the unspecified value can be indeterminate.
5-8) Implicity creates an object array of type
T
with length n
. To be precise, if n > 0 is true, it's equivalent to std::start_lifetime_as<U>(p) where U
is the type "array of n
T
". Otherwise, the function has no effects.
-
T
shall be a complete type, otherwise the program is ill-formed. - The behavior is undefined if:
- Non-null
p
is not suitably aligned for an array ofT
, or - n <= std::size_t(-1) / sizeof(T) is false, or
- n > 0 and
[
(char*)p,
(char*)p + (n * sizeof(T)))
does not denote a region of allocated storage that is a subset of the region of storage reachable throughp
.
- Non-null
Contents |
Parameters
p | - | possible cv-qualified void pointer, denotes the address of the region consisting objects |
n | - | std::size_t, denotes the size of the object array to be created |
Return value
1-4) A pointer to the complete object described above;
5-8) A pointer to the first element of the crated array, if any; otherwise, a pointer that compares equal to
p
. Example
Run this code
enum stream_t : char { FOO, BAR }; struct Foo { stream_t type; int data; }; struct Bar { stream_t type; float data; }; void printFoo(Foo const* ptr) { std::print("Foo({})", ptr->data); } void printBar(Bar const* ptr) { std::print("Bar({})", ptr->data); } void printStream(Stream* stream) { // the function read() returns a pointer to an allocated storage // occupied by data bits written by the external stream device. // and it represents either a Foo or a Bar std::unique_ptr<char[]> buffer = stream->read(); if (buffer[0] == static_cast<char>(FOO)) { // printFoo(reinterpret_cast<Foo*>(buffer.get())); // UB. Since the lifetime of the object is not yet started, trying to // access its data member is a undefined behavior. printFoo(std::start_lifetime_as<Foo>(buffer.get())); // Ok, since the lifetime are now explicitly started. } else { // printBar(reinterpret_cast<Bar*>(buffer.get())); // UB. printBar(std::start_lifetime_as<Bar>(buffer.get())); // OK. } }
Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_start_lifetime_as |
202207L | (C++23) | Explicit lifetime management |
See also
(C++20) |
reinterpret the object representation of one type as that of another (function template) |
(C++17) |
pointer optimization barrier (function template) |