Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcast in a diamond hierarchy

Tags:

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

like image 608
log0 Avatar asked May 18 '11 12:05

log0


1 Answers

The obvious answer is: because the standard says so. The motivation behind this in the standard is that static_cast should be close to trivial—at most, a simple addition or subtraction of a constant to the pointer. Where s the downcast to a virtual base would require more complicated code: perhaps even with an additional entry in the vtable somewhere. (It requires something more than constants, since the position of D relative to A may change if there is further derivation.) The conversion is obviously doable, since when you call a virtual function on an A*, and the function is implemented in D, the compiler must do it, but the additional overhead was considered inappropriate for static_cast. (Presumably, the only reason for using static_cast in such cases is optimization, since dynamic_cast is normally the preferred solution. So when static_cast is likely to be as expensive as dynamic_cast anyway, why support it.)

like image 200
James Kanze Avatar answered Oct 11 '22 16:10

James Kanze