c++ – Prohibiting casting of virtual base class

Question:

Why is casting prohibited in the following code?

class Base
{
};

class Derived : virtual public Base
{
};

int main()
{
    Base *p = new Derived;
    static_cast<Derived *>(p);
    return 0;
}

Answer:

The compiler cannot cast Base* to Derived* , because it does not do a full analysis of the code, which means it does not know exactly how the types are located relative to each other.

If there are only Base and Derived types, then when casting Base* in Derived* you need to add an offset of 0 bytes, since Derived and Base addresses are the same.
However, the compiler assumes that other types may exist, for example

struct Derived2 : virtual Base { char x[1024]; };
struct MostDerived : virtual Derived2, Derived {};

And Base* p can point to an object of that type. Then MostDerived looks like this in memory:

смещение  | что находится
0         | MostDerived
0         | Base
0         | Derived2 
0         | char Derived2::x[1024]
1024      | Derived 

The virtual base class Base , is in Derived2 , the very first base class MostDerived . Because Base is an empty base class and does not take up any memory space. After Derived2 , Derived will be located, already without Base . Therefore, in this case, when casting Base* in Derived* you need to add an offset of 1024 bytes.

Because the compiler does not know which offset to use, it cannot make such a static_cast .

Therefore, only dynamic_cast supported for virtual base types, and then only for types that have virtual functions.

Scroll to Top