C++ Logo

std-discussion

Advanced search

Re: Fwd: Parent pointer to access the parent class from member

From: Andrew Schepler <aschepler_at_[hidden]>
Date: Mon, 29 Jun 2020 07:33:36 -0400
On Sun, Jun 28, 2020 at 6:18 PM Hanspeter Bieri-Ineichen via Std-Discussion
<std-discussion_at_[hidden]> wrote:

> The important ability of C/C++ that classes can be direct members of a
> class allows to access them by a this-pointer offset instead of a pointer
> derefenciation.
>
> To access the parent class from a member the usual way is to store a
> pointer to the parent. There no simple way that uses the member offset. A
> template solution is shown here:
>
> https://stackoverflow.com/questions/62103638/access-parent-class-from-member-without-storing-pointer-of-parent
>
>

I'd note a couple of issues with this solution. It's missing a std::launder
call - without that, the Standard doesn't guarantee that a pointer object
whose value is the address of an object and which has the type of the
object actually acts as a valid pointer to that object. And offsetof is
only conditionally-supported for non-standard-layout class types. But
possibly all that's just more motivation for some better way to do it.

Would it be useful to have something like a parent pointer similar to the
> this-pointer?
>

I take it you're asking about feasibility of a new core language feature.
It couldn't be something as simple as "record_of(lvalue)", since an object
of a given type might be a member of any number of different class types,
or even one of multiple members of the same class type. And anything
requiring extra data to support the feature would be a no-go.

Possibly the language could have something similar to the rules for
static_cast of a pointer to / lvalue which is a base class subobject to a
pointer/reference to a derived class type, when virtual inheritance is not
involved: if the object actually is a base class subobject of an object of
the derived type, it works, but otherwise it's undefined behavior.
Something like member_to_record<&Record::member_name>(ptr) /
member_to_record<&Record::member_name>(lvalue) could similarly be specified
to result in a pointer to / lvalue which is the class object which has the
member as a direct non-static member if the object actually is that member,
or be undefined behavior otherwise.

But the bigger picture issue is, why doesn't the Standard even say that
offsetof will work for non-static members unless the class is
standard-layout, and what's the deal with standard-layout? Note C++17
[intro.object]/7 says "An object of trivially copyable or standard-layout
type shall occupy contiguous bytes of storage." So for class types which
aren't standard-layout, the Standard doesn't actually require that "offset
of a member" even makes sense. Of course, that's normally true, and an
implementation does need some (reasonably efficient) way to access members,
both when the source names the member and via pointer-to-member values, but
C++ implementations have the freedom to sometimes implement members in some
way other than the traditional way of a fixed offset within the class
object's storage, for whatever reasons this might be done. We can imagine
that other ways of implementing members might not make it possible to get
from a member subobject to its containing class object.

-- Andrew Schepler



> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2020-06-29 06:37:01