By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,423 Members | 1,294 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,423 IT Pros & Developers. It's quick & easy.

How dynamic_cast works internally?

P: n/a
Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!

Regards!
Bo

Oct 22 '07 #1
Share this Question
Share on Google+
15 Replies


P: n/a
On Oct 22, 1:51 pm, Bo Yang <struggl...@gmail.comwrote:
Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!

Regards!
Bo
Dynamic cast adjests the offset adress of the perticul type
accordigly .if it does't find the type it will raise the exception (in
case of reference)or it will return null.
Ex:
class base{
};

class base1{
};
class derived : public base1,public base2{
};
deribed temp = new derived;
base2 *p = dynamic_cast<base2*temp;

it will adject the prt offset to base2 part of the temp object.

Br,
akshay saidulu

Oct 22 '07 #2

P: n/a
On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:
Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!

Regards!
Bo
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);
Conceptually, it is like this if is were written in C:

void A_dtor(A* ){}
typeinfo A_RTTI(){
static typeinfo
return typeinfo("A");
}//compiler generated
void(*)() A_vtbl[]={A_dtor,A_RTTI};
struct A{
A_vtbl*vptr;
};
A_ctor(){vptr=A_vtbl;}//compiler generated

void B_dtor(B* ){}
typeinfo B_RTTI(){
static typeinfo
return typeinfo("B");
}//compiler generated
void(*)(B*) B_vtbl[]={B_dtor,B_RTTI};
struct B{
B_vtbl*vptr;
};
B_ctor(){vptr=B_vtbl;}//compiler generated

This is what A and B conceptually look like underneath the hood. Now
when dynamic_cast is called, the compiler generates a function
something like

B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;
}
>From this, it is easy to extrapolate how this can be extended to work
for references.

You can see the reason now why dynamic_cast only works for types that
have "virtual" somewhere, either a function or inheritance.

Lance

Oct 22 '07 #3

P: n/a
On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!
Regards!
Bo

Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;

}
This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.

A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:

struct A
{
virtual ~A() {}
};

bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}

Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.

So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.

Greg
Oct 22 '07 #4

P: n/a
ak************@gmail.com ]:
On Oct 22, 1:51 pm, Bo Yang <struggl...@gmail.comwrote:
>Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!

Regards!
Bo

Dynamic cast adjests the offset adress of the perticul type
accordigly .if it does't find the type it will raise the exception (in
case of reference)or it will return null.
Ex:
class base{
};

class base1{
};
class derived : public base1,public base2{
};
deribed temp = new derived;
base2 *p = dynamic_cast<base2*temp;

it will adject the prt offset to base2 part of the temp object.
Does it just adject the pointer without any additional check of type?

Regards!
Bo
Oct 22 '07 #5

P: n/a
Lance Diduck:
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);
Conceptually, it is like this if is were written in C:

void A_dtor(A* ){}
typeinfo A_RTTI(){
static typeinfo
return typeinfo("A");
}//compiler generated
void(*)() A_vtbl[]={A_dtor,A_RTTI};
struct A{
A_vtbl*vptr;
};
A_ctor(){vptr=A_vtbl;}//compiler generated

void B_dtor(B* ){}
typeinfo B_RTTI(){
static typeinfo
return typeinfo("B");
}//compiler generated
void(*)(B*) B_vtbl[]={B_dtor,B_RTTI};
struct B{
B_vtbl*vptr;
};
B_ctor(){vptr=B_vtbl;}//compiler generated

This is what A and B conceptually look like underneath the hood. Now
when dynamic_cast is called, the compiler generates a function
something like

B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;
}
Thank you for your detailed explaination. And you mean all dynamic_cast
use RTTI inside. yes?
>>From this, it is easy to extrapolate how this can be extended to work
for references.

You can see the reason now why dynamic_cast only works for types that
have "virtual" somewhere, either a function or inheritance.
Yes, class with no virtual has no virtual table at all.

Thanks!

Regards!
Bo
Oct 22 '07 #6

P: n/a
Greg Herlihy :
On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
>On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
>> I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!
Regards!
Bo
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
>B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;

}

This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.

A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:

struct A
{
virtual ~A() {}
};

bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}

Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.

So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!

Regards!
Bo
Oct 22 '07 #7

P: n/a
On Oct 22, 10:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
You can see the reason now why dynamic_cast only works for types that
have "virtual" somewhere, either a function or inheritance.
only for upcast.

downcast must work too regardless to
virtuals:

struct B{};
struct D : B {};
D d;
B & b = dynamic_cast<B&>(d); // OK,
B & b1 = d; // is OK too ;)

DS
Oct 22 '07 #8

P: n/a
On 2007-10-22 09:19:26 -0400, Bo Yang <st********@gmail.comsaid:
>
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!
Well, yes, there is no specification of anything called RTTI in the
language definition. But RTTI is shorthand for the usual implementation
technique for dynamic_cast and for catching exceptions. The compiler
generates type information that's used at runtime to match types as
needed. Hence, RunTime Type Information.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Oct 22 '07 #9

P: n/a
On 2007-10-22 15:19, Bo Yang wrote:
Greg Herlihy :
>On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
>>On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!
Regards!
Bo
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
>>B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;

}

This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.

A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:

struct A
{
virtual ~A() {}
};

bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}

Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.

So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.

So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!
RTTI is part of the C++ standard, do not confuse it with reflection
though. One way to accomplish this (though I do not think that is how it
is done) would be to add a second pointer (in addition to the vtable)
which points to a type object looking something like this:

class Type
{
char name[];
Type* super[];
Type* derived[];
};

That way typeid could (conceptually) be implemented something like this:

template<typename T>
type_info typeid(T t)
{
return type_info(t->typePtr->name)
}

And using some simple tree walking algorithms you can find out if a type
is in the same type-hierarchy as another.

--
Erik Wikström
Oct 22 '07 #10

P: n/a
On Oct 22, 2:23 pm, dasjotre <dasjo...@googlemail.comwrote:
On Oct 22, 10:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
You can see the reason now why dynamic_cast only works for types that
have "virtual" somewhere, either a function or inheritance.

only for upcast.
ahmm, that would be 'downcast' instead
downcast must work too regardless to
and that would be 'upcast' instead
virtuals:

struct B{};
struct D : B {};
D d;
B & b = dynamic_cast<B&>(d); // OK,
B & b1 = d; // is OK too ;)

DS

Oct 22 '07 #11

P: n/a
Erik Wikström
On 2007-10-22 15:19, Bo Yang wrote:
>Greg Herlihy :
>>On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!
Regards!
Bo
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;

}
This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.

A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:

struct A
{
virtual ~A() {}
};

bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}

Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.

So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!

RTTI is part of the C++ standard, do not confuse it with reflection
though. One way to accomplish this (though I do not think that is how it
is done) would be to add a second pointer (in addition to the vtable)
which points to a type object looking something like this:

class Type
{
char name[];
Type* super[];
Type* derived[];
};

That way typeid could (conceptually) be implemented something like this:

template<typename T>
type_info typeid(T t)
{
return type_info(t->typePtr->name)
}

And using some simple tree walking algorithms you can find out if a type
is in the same type-hierarchy as another.
So, C++ type conversion will be time-consuming and space-consuming,
right? And maybe that is why C++ program is much more big than C's?

Regards!
Bo
Oct 23 '07 #12

P: n/a
dasjotre :
On Oct 22, 2:23 pm, dasjotre <dasjo...@googlemail.comwrote:
>On Oct 22, 10:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
>>You can see the reason now why dynamic_cast only works for types that
have "virtual" somewhere, either a function or inheritance.
only for upcast.

ahmm, that would be 'downcast' instead
>downcast must work too regardless to

and that would be 'upcast' instead
>virtuals:

struct B{};
struct D : B {};
D d;
B & b = dynamic_cast<B&>(d); // OK,
B & b1 = d; // is OK too ;)
Yeah, I know. Thanks!
Oct 23 '07 #13

P: n/a
On 2007-10-23 08:55, Bo Yang wrote:
Erik Wikström
>On 2007-10-22 15:19, Bo Yang wrote:
>>Greg Herlihy :
On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
> I can understand static_cast, reinterpret_cast and const_cast, they
>all work at compile time. But I can figure out how the C++'s dynamic-
>cast works? Could you please explain how for me?
>Thanks in advance!
>Regards!
>Bo
Consider this case:
class A{virtual ~A(){};};
class B:public A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;
>
}
This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.

A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:

struct A
{
virtual ~A() {}
};

bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}

Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.

So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!

RTTI is part of the C++ standard, do not confuse it with reflection
though. One way to accomplish this (though I do not think that is how it
is done) would be to add a second pointer (in addition to the vtable)
which points to a type object looking something like this:

class Type
{
char name[];
Type* super[];
Type* derived[];
};

That way typeid could (conceptually) be implemented something like this:

template<typename T>
type_info typeid(T t)
{
return type_info(t->typePtr->name)
}

And using some simple tree walking algorithms you can find out if a type
is in the same type-hierarchy as another.

So, C++ type conversion will be time-consuming and space-consuming,
right? And maybe that is why C++ program is much more big than C's?
As I said, that was only a conceptual example, I do not know how they
really do it in a compiler. But you should notice that all but
dynamic_cast can be done at compile-time without any extra run-time
information, so to claim that C++ casts are more costly than C casts are
not really true. On the other hand, added type-safety obviously does not
come for free, so some extra overhead is inevitable.

--
Erik Wikström
Oct 23 '07 #14

P: n/a
Erik Wikström :
On 2007-10-23 08:55, Bo Yang wrote:
>Erik Wikström
>>On 2007-10-22 15:19, Bo Yang wrote:
Greg Herlihy :
On Oct 22, 2:20 am, Lance Diduck <lancedid...@nyc.rr.comwrote:
>On Oct 22, 4:51 am, Bo Yang <struggl...@gmail.comwrote:Hi,
>> I can understand static_cast, reinterpret_cast and const_cast, they
>>all work at compile time. But I can figure out how the C++'s dynamic-
>>cast works? Could you please explain how for me?
>>Thanks in advance!
>>Regards!
>>Bo
>Consider this case:
>class A{virtual ~A(){};};
>class B:public A{};
>A*a=new B;
>B*b =dynamic_cast<B*>(a);. .
>B* Dynamic_Cast(A*a ){
> if(*((a->vptr)+1)()==B_RTTI())
> return a;
> return 0;
>>
>}
This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.
>
A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:
>
struct A
{
virtual ~A() {}
};
>
bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}
>
Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<has only the "A"
class declaration with which to work here.
>
So how is dynamic_cast<supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!
RTTI is part of the C++ standard, do not confuse it with reflection
though. One way to accomplish this (though I do not think that is how it
is done) would be to add a second pointer (in addition to the vtable)
which points to a type object looking something like this:

class Type
{
char name[];
Type* super[];
Type* derived[];
};

That way typeid could (conceptually) be implemented something like this:

template<typename T>
type_info typeid(T t)
{
return type_info(t->typePtr->name)
}

And using some simple tree walking algorithms you can find out if a type
is in the same type-hierarchy as another.
So, C++ type conversion will be time-consuming and space-consuming,
right? And maybe that is why C++ program is much more big than C's?

As I said, that was only a conceptual example, I do not know how they
really do it in a compiler. But you should notice that all but
dynamic_cast can be done at compile-time without any extra run-time
information, so to claim that C++ casts are more costly than C casts are
not really true. On the other hand, added type-safety obviously does not
come for free, so some extra overhead is inevitable.
Yeah, thank you very much!

Regards!
Bo
Oct 23 '07 #15

P: n/a
On Oct 23, 9:56 am, Erik Wikström <Erik-wikst...@telia.comwrote:

[...]
So, C++ type conversion will be time-consuming and space-consuming,
right? And maybe that is why C++ program is much more big than C's?
As I said, that was only a conceptual example, I do not know how they
really do it in a compiler. But you should notice that all but
dynamic_cast can be done at compile-time without any extra run-time
information, so to claim that C++ casts are more costly than C casts are
not really true. On the other hand, added type-safety obviously does not
come for free, so some extra overhead is inevitable.
The standard doesn't say anything about time or space overhead
for a cast, but typically: reinterpret_cast and const_cast
generate no code, static_cast will sometimes generate no code,
and rarely more than one or two machine instructions (except for
static_cast's involving floating point types on machines without
hardware floating point support), and dynamic_cast will involve
10's or 100's of machine instructions, depending on the
case.

Note too that in some cases, the compiler can resolve the
dynamic_cast directly, and implement it much as it would a
static_cast. I think all compilers do this for dynamic_cast's
from derived to base.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 23 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.