Accessing private data with reinterpret_cast

孤街浪徒 提交于 2020-08-22 11:56:46

问题


This seems to compile and access the private data successfully. Is this well-defined behavior?

#include <iostream>
#include <string>

using std::string;

class foo {
    string private_data = "Hello World";
};

int main()
{
    foo f;
    auto* pprivate_data = reinterpret_cast<string*>(&f);
    std::cout << *pprivate_data << '\n';
}

This question is sort of similar, but I believe it doesn't address my question.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/63112631/accessing-private-data-with-reinterpret-cast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!