Why can’t static_cast be used to down-cast when virtual inheritance is involved?

[*]

The technical problem is that there’s no way to work out from a Base* what the offset is between the start of the Base sub-object and the start of the Derived object.

In your example it appears OK, because there’s only one class in sight with a Base base, and so it appears irrelevant that the inheritance is virtual. But the compiler doesn’t know whether someone defined another class Derived2 : public virtual Base, public Derived {}, and is casting a Base* pointing at the Base subobject of that. In general[*], the offset between the Base subobject and the Derived subobject within Derived2 might not be the same as the offset between the Base subobject and the complete Derived object of an object whose most-derived type is Derived, precisely because Base is virtually inherited.

So there’s no way to know the dynamic type of the complete object, and different offsets between the pointer you’ve given the cast, and the required result, depending what that dynamic type is. Hence the cast is impossible.

Your Base has no virtual functions and hence no RTTI, so there certainly is no way to tell the type of the complete object. The cast is still banned even if Base does have RTTI (I don’t immediately know why), but I guess without checking that a dynamic_cast is possible in that case.

[*] by which I mean, if this example doesn’t prove the point then keep adding more virtual inheritance until you find a case where the offsets are different 😉

Leave a Comment