C++ Logo


Advanced search

P1839 and the object representation of subobjects

From: Giuseppe D'Angelo <giuseppe.dangelo_at_[hidden]>
Date: Tue, 21 Jul 2020 13:51:17 +0200

There's a long-ish thread [1] on the Qt mailing lists around using
offsetof to obtain a pointer to a data member of a class (given a
pointer to an object of that class), and vice versa, given a pointer to
a data member, obtain a pointer to the enclosing object. Simplified:

> class QObject { // non standard layout
> QObjectPrivate *d_ptr;
> public:
> virtual ~QObject();
> C1 c1; // possibly [[no_unique_address]]
> C2 c2;
> };

And now, given

> auto off = offsetof(QObject, c1); // OK, conditionally supported in 17

Go from a pointer to QObject to a pointer to c1:

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

and vice versa from c1 to the containing object:

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

Now, without P1839, the mere pointer arithmetic is already UB
([expr.add§6], as the paper explains) and one of the goals is fixing
*that*. Something that the paper doesn't seem to do however is to give
meaning to the above expressions: nowhere one is allowed to do the above
casts (from within an object's representation to the actual object
"stored there").

Should it try and go that far? Was something like this ever proposed or
discussed, maybe elsewhere? It would actually make offsetof *useful* (at
the moment, the legal use cases sound rather limited).


[1] https://lists.qt-project.org/pipermail/development/2020-July/039996.html
Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

Received on 2020-07-21 06:54:40