Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/memory/start lifetime as"

From cppreference.com
< cpp‎ | memory
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 create}}
+
{{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

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(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)



Explicit lifetime management
start_lifetime_asstart_lifetime_as_array
(C++23)(C++23)

 
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 through p, 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 of T, 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 through p.

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

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) [edit]
(C++17)
pointer optimization barrier
(function template) [edit]