Maybe my question is not perfectly formed, but my code will make everything clear.
#include <iostream>
using namespace std;
struct A{int n;};
struct B{int n;};
struct C : A, B{};
int main()
{
C c;
C* pc = &c;
std::cout<<"TEST1"<<std::endl;
cout << static_cast<B*>(pc) << "\n";
cout << reinterpret_cast<B*>(pc)<<"\n\n";
std::cout<<"TEST2"<<std::endl;
cout << static_cast<A*>(pc) << "\n";
cout << reinterpret_cast<A*>(pc)<<"\n";
}
And the output is:
TEST1
0042F830
0042F82C
TEST2
0042F82C
0042F82C
I know that using reinterpret_cast is ill formed design. I am not thinking about the design but the behavior is what bother me. Can anyone explain why casting different ways gives different results the first time but the same result the second time??
Defining a class also means defining a memory layout. In its simplest form the members are laid out consecutively, e.g.
struct A {
int n;
};
and in memory
| Address | Size | Member |
|----------+------+--------+
| 0042F82C | 4 | n |
The same happens with base classes
struct C : A, B {
};
potential memory layout
| Address | Size | Member |
|----------+------+--------+
| 0042F82C | 4 | A::n |
| 0042F830 | 4 | B::n |
Now you have a pointer pc
to an object of type C
. Using static_cast
takes into account the layout of members and base classes within an object.
Therefore, you get the proper address for the A
or B
part.
Using reinterpret_cast
on the other side, just reuses a pointer and pretends it points to another type.
Explanation
Unlike static_cast, but like const_cast, the reinterpret_cast expression does not compile to any CPU instructions. It is purely a compiler directive which instructs the compiler to treat the sequence of bits (object representation) of expression as if it had the type new_type.
This is the reason, why you get the same address value.