When is static cast safe when you are using multiple inheritance?

user34537 picture user34537 · Oct 17, 2011 · Viewed 8.9k times · Source

I found myself in a situation where I know what type something is. The Type is one of three (or more) levels of inheritance. I call factory which returns B* however T is either the highest level of a type (if my code knows what it is) or the 2nd level.

Anyways, I did a static_cast in the template which is the wrong thing to do. My question is WHEN can I static cast safely? Is there ever such a time? I did it in this case because I'd rather get compile errors when I accidentally have T as something wacky which (has happened and) dynamic cast ignores (and returns null). However when I know the correct type the pointer is not adjusted causing me to have a bad pointer. I'm not sure why static cast is allowed in this case at all.

When can I use static_cast for down casting safely? Is there ever a situation? Now it seems like it always is wrong to use a static_cast (when the purpose is to down cast)

Ok I figured out how to reproduce it.

#include <iostream>
struct B { virtual void f1(){} };
struct D1 : B {int a;};
struct D2 : B {int a, b; };
struct DD : D1, D2 {};

int main(){
void* cptr = new DD(); //i pass it through a C interface :(
B*  a = (B*)cptr;
D2* b = static_cast<D2*>(a); //incorrect ptr
D2* c = dynamic_cast<D2*>(a); //correct ptr
std::cout << a << " " <<b << " " <<c;
}

Answer

Ben Voigt picture Ben Voigt · Oct 17, 2011

A cross-cast:

struct Base1 { virtual void f1(); };
struct Base2 { virtual void f2(); };
struct Derived : Base1, Base2 {};

Base1* b1 = new Derived();
Base2* b2 = dynamic_cast<Base2*>(b1);

requires use of dynamic_cast, it cannot be done with static_cast (static_cast should have caused a compile-time error). dynamic_cast will also fail if either base class is not polymorphic (the presence of virtual functions is NOT optional).

See this explanation on MSDN