使用 reinterpret_cast 访问私人数据
Accessing private data with reinterpret_cast
这似乎成功编译并访问了私有数据。这是定义明确的行为吗?
#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 问题有点相似,但我认为它没有解决我的问题。
不,行为未定义。为了使 reintepret_cast
有意义,这两个对象必须可以相互转换
[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 ]
可能适用的唯一要点是关于标准布局的要点类。如果我们查阅该定义,我们会看到
[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,
- [...]
有一个紧迫的问题。对象的任何非静态数据成员本身必须是标准布局。不能保证 std::string
是标准布局类型。所以行为是未定义的。
是的,这很好,条件是 std::string
(因此 class foo
)是标准布局(它 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]
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.
显然,这只适用于第一个非静态数据成员。
这似乎成功编译并访问了私有数据。这是定义明确的行为吗?
#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 问题有点相似,但我认为它没有解决我的问题。
不,行为未定义。为了使 reintepret_cast
有意义,这两个对象必须可以相互转换
[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 ]
可能适用的唯一要点是关于标准布局的要点类。如果我们查阅该定义,我们会看到
[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,
- [...]
有一个紧迫的问题。对象的任何非静态数据成员本身必须是标准布局。不能保证 std::string
是标准布局类型。所以行为是未定义的。
是的,这很好,条件是 std::string
(因此 class foo
)是标准布局(它 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]
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.
显然,这只适用于第一个非静态数据成员。