Search code examples
c++castingvirtual-inheritancestatic-castdiamond-problem

Downcast in a diamond hierarchy


Why static_cast cannot downcast from a virtual base ?

struct A {};
struct B : public virtual A {};
struct C : public virtual A {};
struct D : public B, public C {};

int main()
{
  D d;
  A& a = d;
  D* p = static_cast<D*>(&a); //error
}  

g++ 4.5 says:

 error: cannot convert from base ‘A’ to derived type ‘D’ via virtual base ‘A’

The solution is to use dynamic_cast ? but why. What is the rational ?

-- edit --
Very good answers below. No answers detail exactly how sub objects and vtables end up to be ordered though. The following article gives some good examples for gcc:
http://www.phpcompiler.org/articles/virtualinheritance.html#Downcasting


Solution

  • Because if the object was actually of type E (derived from D), the location of A subobject relative to D subobject could be different than if the object is actually D.

    It actually already happens if you consider instead casting from A to C. When you allocate C, it has to contain instance of A and it lives at some specific offset. But when you allocate D, the C subobject refers to the instance of A that came with B, so it's offset is different.