Accessing private data with reinterpret_cast
No, the behavior is undefined. For such a reintepret_cast
to have meaning, the two objects must be interconvertible
[basic.compound]
4 Two objects a and b are pointer-interconvertible if:
- they are the same object, or
- one is a union object and the other is a non-static data member of that object ([class.union]), or
- one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object ([class.mem]), or
- there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a
reinterpret_cast
. [ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address. — end note ]
The only bullet that might apply is the one about standard layout classes. If we consult that definition, we see
[class.prop]
3 A class S is a standard-layout class if it:
- has no non-static data members of type non-standard-layout class (or array of such types) or reference,
- [...]
there is an immediate problem. Any non-static data members of the object must be standard layout themselves. There is no guarantee std::string
is a standard layout type. So the behavior is undefined.
Yes, this is fine on condition std::string
(and thus class foo
) is standard-layout (it is in libstdc++, libc++ and MSVC STL). Per class.mem/26 :
If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member [...] [Note: The object and its first subobject are pointer-interconvertible ([basic.compound], [expr.static.cast]). — end note]
And basic.compund/4:
Two objects a and b are pointer-interconvertible if: [...]
- one is a standard-layout class object and the other is the first non-static data member of that object [...]
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast.
Obviously, this only works for the first non-static data member.