AFAIK, for pointers/references static_cast, if a class definition is not visible to compiler at this point, then static_cast will be behave like reinterpret_cast.
Why is static_cast unsafe for pointers/references and is safe for numeric values?
In short, because of multiple inheritance.
In long:
Output:
Note that in order to convert correctly to B*, static_cast has to change the pointer value. If the compiler didn’t have the class definition for C, then it wouldn’t know that B was a base class, and it certainly wouldn’t know what offset to apply.
But in that situation where no definition is visible, static_cast doesn’t behave like reinterpret_cast, it’s forbidden:
A plain C-style cast,
(B*)(&c)does what you say: if the definition of struct C is visible, showing that B is a base class, then it’s the same as a static_cast. If the types are only forward-declared, then it’s the same as a reinterpret_cast. This is because it’s designed to be compatible with C, meaning that it has to do what C does in cases which are possible in C.static_cast always knows what to do for built-in types, that’s really what built-in means. It can convert int to float, and so on. So that’s why it’s always safe for numeric types, but it can’t convert pointers unless (a) it knows what they point to, and (b) there is the right kind of relationship between the pointed-to types. Hence it can convert
inttofloat, but notint*tofloat*.As AndreyT says, there is a way that you can use
static_castunsafely, and the compiler probably won’t save you, because the code is legal:One of the things
static_castcan do is “downcast” a pointer to a derived class (in this case, C is a derived class of A). But if the referand is not actually of the derived class, you’re doomed. Adynamic_castwould perform a check at runtime, but for my example class C you can’t use adynamic_cast, because A has no virtual functions.You can similarly do unsafe things with
static_castto and fromvoid*.