c++castingrttidowncast

Can reinterpret_cast be considered as an unsafe workaround when dynamic_cast is unavailable?


I am using C++ to write some components in a toy x86 kernel, and I was in a situation where I had to downcast a pointer type. I had an interface and its implementation like this,

class ITerminalWriter {
    // members
};

class BasicTerminalWriter : public ITerminalWriter {
    // implementation
};

And I had a pointer to a BasicTermialWriter instance which had upcasted to ITerminalWriter* and needed to downcast it back to BasicTermialWriter*.

Since RTTI is not available for me, I was considering using reinterpret_cast to perform the downcast since the involved types were clear to me in my context. But later, I made some modifications to the design which made the downcast unnecessary.

But I am still curious whether reinterpret_cast can actually be used as an "ugly" workaround for unavailabilty of dynamic_cast in situations like mine.


Solution

  • No, reinterpret_cast is wrong for this use case.

    It will almost always cause undefined behavior by the standard when used this way (there is only an exception in certain constellations where the classes are standard-layout) and can potentially (depending on the class layout) cause immediate problems in practice.

    The correct alternative to dynamic_cast is static_cast. It doesn't require RTTI and will perform pointer adjustments that are necessary correctly (while reinterpret_cast doesn't).

    However, static_cast will not perform any validity check like dynamic_cast does. Instead, if the pointer is not actually a pointer to a base class subobject of an object of the derived type that you cast to, then static_cast will simply have undefined behavior. dynamic_cast on the other hand performs a check and would return a null pointer on failure.

    More generally, there are only a very small number of specific use cases for reinterpret_cast at all that do not lead to undefined behavior. Never try to use it before considering other casts like static_cast.