Date: Sun, 3 Apr 2022 03:11:54 -0400
Hello,
I believe there is a flaw in the current standard that results in
allocators that acquire memory in the form char[]/unsigned
char[]/std::byte[] by arbitrary means to be unimplementable.
The standard appears to intend implicit object creation to be used to
within allocate() to create a T[] inside the acquired byte array, but I
believe that there is no way to take advantage of that while complying
with the allocator interface. Implicit object creation can always create
a T[], but there is no way to get a pointer to it:
* If T is implicit-lifetime, a pointer to the first element of the byte
array can be converted to a T* and laundered to get a pointer to an
implicitly created T. However, this would require creating an array
element, thus violating [allocator.requirements]/36.
* If T is not implicit-lifetime, there's no way to get a pointer to it.
Attempting to launder results in unconditional UB, since launder
requires the target object to already exist.
This problem is described in more detail in the proposal.
One solution that looks promising is
|std::launder(reinterpret_cast<T(*)[]>(byte_array()))|, but it is UB to
instantiate launder with a template argument being an incomplete type
under [res.on.functions]/2.5. I propose to remove this restriction for
launder.
A live version of the proposal is at [0], and a copy is attached.
[0]: https://randomcat.org/cpp_next/specification/launder_arrays.html
I believe there is a flaw in the current standard that results in
allocators that acquire memory in the form char[]/unsigned
char[]/std::byte[] by arbitrary means to be unimplementable.
The standard appears to intend implicit object creation to be used to
within allocate() to create a T[] inside the acquired byte array, but I
believe that there is no way to take advantage of that while complying
with the allocator interface. Implicit object creation can always create
a T[], but there is no way to get a pointer to it:
* If T is implicit-lifetime, a pointer to the first element of the byte
array can be converted to a T* and laundered to get a pointer to an
implicitly created T. However, this would require creating an array
element, thus violating [allocator.requirements]/36.
* If T is not implicit-lifetime, there's no way to get a pointer to it.
Attempting to launder results in unconditional UB, since launder
requires the target object to already exist.
This problem is described in more detail in the proposal.
One solution that looks promising is
|std::launder(reinterpret_cast<T(*)[]>(byte_array()))|, but it is UB to
instantiate launder with a template argument being an incomplete type
under [res.on.functions]/2.5. I propose to remove this restriction for
launder.
A live version of the proposal is at [0], and a copy is attached.
[0]: https://randomcat.org/cpp_next/specification/launder_arrays.html
-- Jason Cobb
Received on 2022-04-03 07:11:57