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.
The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.
The reinterpret_cast operator performs potentially unsafe type casts. It is most often used to cast a pointer to a different pointer type. Casting a pointer to a different pointer and back is usually safe and yields the original value.
Although the reinterpret_cast itself might be unspecified behaviour, attempting to access the parameters once you've done the cast is undefined behaviour.
None of the casts happen at compile time. You only have the data at runtime, in general.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With