C++ Logo

std-proposals

Advanced search

Re: P1839 and the object representation of subobjects

From: language.lawyer_at <language.lawyer_at_[hidden]>
Date: Tue, 21 Jul 2020 22:44:13 +0300
On 21/07/2020 22:26, Ville Voutilainen via Std-Proposals wrote:
> On Tue, 21 Jul 2020 at 22:23, Ville Voutilainen
> <ville.voutilainen_at_[hidden]> wrote:
>>
>> On Tue, 21 Jul 2020 at 22:19, Thiago Macieira via Std-Proposals
>> <std-proposals_at_[hidden]> wrote:
>>>
>>> On Tuesday, 21 July 2020 09:37:08 PDT Jason McKesson via Std-Proposals wrote:
>>>>> There is an object of the proper type at the address. The problem is we
>>>>> can't get to the address without UB in the first place because the
>>>>> pointer arithmetic is undefined.
>>>>
>>>> But P1839 solves that problem. And this post was written under the
>>>> rules governed by P1839.
>>>
>>> That was not the consensus of the discussions so far.
>>>
>>> P1839 may need a stronger wording to make it explicit that pointer arithmetic
>>> on the char-sized backing buffer is well-defined.
>>
>> I have no idea how
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1839r2.pdf
>> can be any *more* explicit about that. It says that both in the design
>> part of the paper and in the wording.
>
> ..and it also explicitly allows going back to an object pointer from
> an object representation pointer,
> via a reinterpret_cast. It explicitly makes well-defined all the
> things that we're worried about
> in the context of QProperty.

In the code:

QObject *qoptr = ~~~;
auto c1ptr = reinterpret_cast<C1 *>(
   reinterpret_cast<byte *>(qoptr) + off
);
assert(c1ptr == &qoptr->c1);

`reinterpret_cast<byte *>(qoptr) + off` still points to an element of object representation of the `*qoptr` object, not the first element of object representation of its member subobject at the specified offset. P1839R2's changes to reinterpret_cast wording allow conversion between a pointer to an object and its object representation or the first element of its object representation. This code requires std::launder to get a pointer to member subobject.


In the code:

auto qoptr2 = reinterpret_cast<QObject *>(
   reinterpret_cast<byte *>(c1ptr) - off
);
assert(qoptr == qoptr2);

if `c1ptr` really points to member subobject, `reinterpret_cast<byte *>(c1ptr)` points to the **first** element of its object representation, so subtracting a positive number from such a pointer value is UB because of [expr.add]/4.


So, P1839R2 makes well-defined none of the things we're worried about in the context of QProperty.

Received on 2020-07-21 14:47:33