On Sun, Jun 28, 2020 at 6:18 PM Hanspeter Bieri-Ineichen via Std-Discussion <std-discussion@lists.isocpp.org> 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@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion