1

I am curious as to how casting pointers to derived and base-classes actually works. Here is an example:

struct A {};
struct B : A {};

// Boxing a pointer to an instance of B
void* p = new B();

Now, let´s say I want to access possible members or methods of A through the pointer p.

A* a1 = (A*)p;
A* a2 = (A*)((B*)p);

Which one is correct? Is there a difference at all?
Could you tell me where I can get further information on this subject?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Beta Carotin
  • 1,659
  • 1
  • 10
  • 27

1 Answers1

2

In this case, no difference in practice.

But there could be difference if there is multiple inheritance:

#include <cstdio>

struct A { int x; };
struct B { int y; };

struct C : B, A {};

int main() {
    void* c = new C();
    printf("%p\n", c);             // 0x1000
    printf("%p\n", (A*) c);        // 0x1000
    printf("%p\n", (A*) ((C*) c)); // 0x1004
    return 0;
}

or the subclass has a virtual method but the parent does not[1], including using virtual inheritance[2].

In terms of the standard, as OP uses C-style cast, which in this case is equivalent to static_cast.

The cast sequence B*void*B*A* is valid, where the first two cast will return back the same pointer as required by §5.2.9[expr.static.cast]/13, and the last cast works as a pointer conversion §4.10[conv.ptr]/3.

However, the cast sequence B*void*A* will actually give undefined result, because, well, the result is not defined in §5.2.9/13 ☺.


[1]:

#include <cstdio>

struct A { int x; };
struct C : A { virtual void g() {} };

int main() {
    void* c = new C();
    printf("%p\n", c);              // 0x1000
    printf("%p\n", (A*) c);         // 0x1000
    printf("%p\n", (A*) ((C*) c));  // 0x1008
    return 0;
}

[2]:

#include <cstdio>

struct A { int x; };
struct C : virtual A {};

int main() {
    void* c = new C();
    printf("%p\n", c);              // 0x1000
    printf("%p\n", (A*) c);         // 0x1000
    printf("%p\n", (A*) ((C*) c));  // 0x1008
    return 0;
}
Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005