Created on 2024-10-23.00:00:00 last changed 3 weeks ago
Proposed resolution:
This wording is relative to N4993.
Modify [obj.lifetime] as indicated:
[Drafting note: The proposed resolution does not alter the behavior for erroneous bits. Therefore, a call to std::start_lifetime_as may have erroneous behavior when used on storage with indeterminate bits, despite not accessing that storage. An alternative resolution would be to produce objects whose value is erroneous.]
template<class T> T* start_lifetime_as(void* p) noexcept; template<class T> const T* start_lifetime_as(const void* p) noexcept; template<class T> volatile T* start_lifetime_as(volatile void* p) noexcept; template<class T> const volatile T* start_lifetime_as(const volatile void* p) noexcept;-1- Mandates: […]
-2- Preconditions: […] -3- Effects: Implicitly creates objects ([intro.object]) within the denoted region consisting of an object a of type `T` whose address is `p`, and objects nested within a, as follows: The object representation of a is the contents of the storage prior to the call to `start_lifetime_as`. The value of each created object o of trivially copyable type ([basic.types.general]) `U` is determined in the same manner as for a call to bit_cast<U>(E) ([bit.cast]), where `E` is an lvalue of type `U` denoting o, except that the storage is not accessed and that for each indeterminate bit b in the value representation of the result, the smallest object containing that bit b has indeterminate value where the behavior would otherwise be undefined. The value of any other created object is unspecified.
Consider the motivating example from P2590R2: Explicit lifetime management:
struct X { int a, b; }; X* make_x() { X* p = std::start_lifetime_as<X>(myMalloc(sizeof(struct X)); p->a = 1; p->b = 2; return p; }
Assuming that `myMalloc` does not initialize the bytes of storage, this example has undefined behavior because the value of the resulting object of trivially copyable type `X` is determined as if by calling std::bit_cast<X>(a) for the implicitly-created object `a` of type `X` ([obj.lifetime] paragraph 3), whose object representation is filled with indeterminate bytes obtained from `myMalloc`. Such a call to `std::bit_cast` has undefined behavior because `std::bit_cast` does not tolerate the creation of an `int` where bits in the value representation are indeterminate ([bit.cast] paragraph 2), and such an `int` is the smallest enclosing object of some of the indeterminate bits.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-10-26 16:00:25 | admin | set | messages: + msg14442 |
2024-10-23 00:00:00 | admin | create |