Search code examples
c++inheritancecastingreinterpret-caststatic-cast

Casting to different Base classes gives different result. C++


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??


Solution

  • 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.