Subject: Re: [std-proposals] P1839 and the object representation of subobjects
From: Jason McKesson (jmckesson_at_[hidden])
Date: 2020-07-21 18:38:40
On Tue, Jul 21, 2020 at 5:31 PM Giuseppe D'Angelo via Std-Proposals
> Il 21/07/20 17:01, Jason McKesson via Std-Proposals ha scritto:
> > We technically already have a way to do that: `std::launder`:
> > ```
> > auto byte_ptr = reinterpret_cast<byte *>(qoptr);
> > auto c1ptr = std::launder(reinterpret_cast<C1 *>(byte_ptr + off);
> > ```
> > If there is an object of type `C1` at the given address, then
> > `std::launder` will return a pointer to it. This is the purpose of
> > `launder`.
> I'm not 100% sure that P1839 would allow for the above reintepret_cast,
> though. And if it does, would std::launder still be necessary?
I'm not sure what you mean, as there are two `reinterpret_cast`s, and
both of them are 100% legal even in C++98. You can always do that kind
of reinterpret_cast. It's the *use of the pointers* whose legality is
The parts that are illegal in C++ as it currently stands are:
1: `byte_ptr + off`. Pointer arithmetic in C++ is based on arrays
(which for a single object is treated as a 1-element array).
`byte_ptr` does not point to an array of `char`, so pointer arithmetic
2: The pointer resulting from `reinterpret_cast<C1*>` does not
*actually* point to the subobject of type `C1` within the other
object, even if the address `qoptr + off` is the address of that
P1839R2 solves problem number 1, as stated by its wording:
> [intro.object]/2 (inserted)
> The object representation of an object `a` of type cv T is a sequence
> of N cv unsigned char objects that occupy the same storage as `a`,
> where N is equal to sizeof(T). The sequence is considered to be
> an array of N T if the object occupies contiguous bytes of storage
> [reinterpret.cast]/7.2 (modified)
> If `a` occupies contiguous bytes of storage and T2 is unsigned char, char or std::byte, the result is a pointer to the first element of the object representation of `a`
So it's quite clear that `byte_ptr` points to the first element of
`qoptr`'s object representation. And it's clear that this object
representation is an array of bytes if `qoptr` points to a type that
Note that the proposal P1945 is the part that expands "object occupies
contiguous bytes of storage" to (many) more types than would currently
be the case.
As for #2, `std::launder` from C++17 solves this problem:
> Requires: `p` represents the address `A` of a byte in memory. An
> object X that is within its lifetime (6.8) and whose type is similar (7.5)
> to T is located at the address `A`. All bytes of storage that would be
> reachable through the result are reachable through `p` (see below).
> Returns: A value of type T* that points to `X`.
There is an object of type `C1` at the address `byte_ptr + off`;
therefore, `launder` retrieves a pointer to it.
STD-PROPOSALS list run by herb.sutter at gmail.com
Standard Proposals Archives on Google Groups