Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is dynamic_cast implemented

Consider this simple hierarchy:

class Base { public: virtual ~Base() { } }; class Derived : public Base { }; 

Trying to downcast Base* p to Derived* is possible using dynamic_cast<Derived*>(p). I used to think dynamic_cast works by comparing the vtable pointer in p to the one in a Derived object.

But what if we derive another class from Derived? We now have:

class Derived2 : public Derived { }; 

In this case:

Base* base = new Derived2; Derived* derived = dynamic_cast<Derived*>(base); 

We still get a successful downcast, even though the vtable pointer in Derived2 has nothing to do with a vtable pointer in Derived.

How does it actually work? How can the dynamic_cast know whether Derived2 was derived from Derived (what if Derived was declared in a different library)?

I am looking for specific details about how this actually works (preferably in GCC, but others are fine too). This question is not a duplicate of this question (which doesn't specify how it actually works).

like image 707
Avidan Borisov Avatar asked Aug 21 '13 14:08

Avidan Borisov


People also ask

What is difference between Static_cast and dynamic_cast?

static_cast − This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. dynamic_cast −This cast is used for handling polymorphism.

What is dynamic_cast used for?

The primary purpose for the dynamic_cast operator is to perform type-safe downcasts. A downcast is the conversion of a pointer or reference to a class A to a pointer or reference to a class B , where class A is a base class of B .

Does dynamic_cast required RTTI?

The fact, that the cast is safe is known by the compiler at compile time. This means, that dynamic_cast does not need to use RTTI.

Should I use dynamic_cast?

This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. This is exclusively to be used in inheritence when you cast from base class to derived class.


1 Answers

How can the dynamic_cast know whether Derived2 was derived from Derived (what if Derived was declared in a different library)?

The answer to that is surprisingly simple: dynamic_cast can know this by keeping this knowledge around.

When the compiler generates code it keeps around the data about the class hierarchies in some sort of table that dynamic_cast can look up later. That table can be attached to the vtable pointer for easy lookup by the dynamic_cast implementation. The data neeeded for typeid for those classes can also be stored along with those.

If libraries are involved, this sort of thing usually requires these type information structures to be exposed in the libraries, just like with functions. It is possible, for example, to get a linker error that looks like "Undefined reference to 'vtable for XXX'" (and boy, are those annoying!), again, just like with functions.

like image 105
R. Martinho Fernandes Avatar answered Sep 24 '22 07:09

R. Martinho Fernandes