473,397 Members | 2,056 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

How expensive is getting the RTTI ?

I was just curious to know how are calls like say dynamic_cast
implemented. Is it really expensive to get the exact type of an object
being pointed to by the baseclass pointer?

The reason I am asking is because of the well known issue of pointer
arithmetic not going well with polymorphism. Consider a function like

void myFunc( baseC ptr[], int length) {
for (int i=0; i<length; i++)
ptr[i].someField = somevalue;
}

Here baseC is some base class. Now, this function will not work as
intended if I pass in an array of derived class objects. (because
ptr[i] gets mapped to (ptr + i*sizeof(baseC)) )

Is it really expensive for the Compiler to generate proper code here
rather than just the sizeof addition? By proper code, I mean get the
type info for the actual objects pointed at by ptr and use that size.
If it indeed is that expensive, can it just do it for cases like above
where I can specifically give some kind of hint that myFunc can
"possibly" be invoked with an array of derived class objects.

Thanks,
Vikram

Jun 30 '06 #1
9 1801

Vikram wrote:
I was just curious to know how are calls like say dynamic_cast
implemented. Is it really expensive to get the exact type of an object
being pointed to by the baseclass pointer?

The reason I am asking is because of the well known issue of pointer
arithmetic not going well with polymorphism. Consider a function like

void myFunc( baseC ptr[], int length) {
for (int i=0; i<length; i++)
ptr[i].someField = somevalue;
}

Here baseC is some base class. Now, this function will not work as
intended if I pass in an array of derived class objects. (because
ptr[i] gets mapped to (ptr + i*sizeof(baseC)) )

Is it really expensive for the Compiler to generate proper code here
rather than just the sizeof addition? By proper code, I mean get the
type info for the actual objects pointed at by ptr and use that size.
If it indeed is that expensive, can it just do it for cases like above
where I can specifically give some kind of hint that myFunc can
"possibly" be invoked with an array of derived class objects.

Thanks,
Vikram


Oops! I think I already realized one of the reasons compilers dont even
try this. Like derived classes can be defined in different files so no
way a compiler would know about them when it is looking at this current
file.

Anyway, please let me know how expensive is getting run-time type info
in general. Dynamic_cast in particular

Jun 30 '06 #2
> Anyway, please let me know how expensive is getting run-time type info
in general. Dynamic_cast in particular

Generally how exactly expensive RTTI is an issue of quality of
implementation. RTTI is almost certainly built on top of the virtual
function mechanism. It can be implemented as an anonymous virtual
function that traces down the inheritance graph. So you can assume O(n)+
complexity for n level of inheritance [Correct me if I am so wrong here.]

There is a polymorphic_downcast<> function template from boost cast
library you can use. It acts like dynamic cast for debug builds, and
like static_cast for release builds. Nevertheless, use it with great
caution.

Regards,
Ben
Jun 30 '06 #3

benben wrote:
Anyway, please let me know how expensive is getting run-time type info
in general. Dynamic_cast in particular

Generally how exactly expensive RTTI is an issue of quality of
implementation. RTTI is almost certainly built on top of the virtual
function mechanism. It can be implemented as an anonymous virtual
function that traces down the inheritance graph. So you can assume O(n)+
complexity for n level of inheritance [Correct me if I am so wrong here.]

There is a polymorphic_downcast<> function template from boost cast
library you can use. It acts like dynamic cast for debug builds, and
like static_cast for release builds. Nevertheless, use it with great
caution.

Regards,
Ben


Thanks Ben. As of now, instead of dynamic_cast, we have just put
virtual int getSize() { return sizeof(*this);}
in all the classes of the hierarchy (some 4-5). And in myFunc, we did
ptr + i*ptr->getSize()
instead of using ptr[i]

I know this is not very elegant and especially if someone adds a new
class, he _has_ to override this method. But this is some old legacy
code and I dont want to change a lot here. And am pretty sure, there
wont be new classes added.

Thanks,
Vikram

Jun 30 '06 #4
benben wrote:
Generally how exactly expensive RTTI is an issue of quality of
implementation. RTTI is almost certainly built on top of the virtual
function mechanism. It can be implemented as an anonymous virtual
function that traces down the inheritance graph. So you can assume O(n)+
complexity for n level of inheritance [Correct me if I am so wrong here.]


I don't believe that to be the case. My understanding is that because
the vtable for each instance of a particular concrete class is the
same, and all the information necessary to construct it is available at
compile time, virtual dispatch overhead is independent of inheritance
depth -- basically it's an extra pointer deref, period (plus an
addition op for indexing? I'm not 100% sure). The only thing that has
to be done at runtime is to determine, by looking at the hidden vtable
pointer in each polymorphic class instance, which vtable to use.

Luke

Jun 30 '06 #5
Vikram schrieb:
benben wrote:
Anyway, please let me know how expensive is getting run-time type info
in general. Dynamic_cast in particular


Generally how exactly expensive RTTI is an issue of quality of
implementation. RTTI is almost certainly built on top of the virtual
function mechanism. It can be implemented as an anonymous virtual
function that traces down the inheritance graph. So you can assume O(n)+
complexity for n level of inheritance [Correct me if I am so wrong here.]

There is a polymorphic_downcast<> function template from boost cast
library you can use. It acts like dynamic cast for debug builds, and
like static_cast for release builds. Nevertheless, use it with great
caution.

Regards,
Ben


Thanks Ben. As of now, instead of dynamic_cast, we have just put
virtual int getSize() { return sizeof(*this);}
in all the classes of the hierarchy (some 4-5). And in myFunc, we did
ptr + i*ptr->getSize()
instead of using ptr[i]


I hope you convert ptr to (char*) before. Doing ptr[i*ptr->getSize()] is
not what you want.

Thomas
Jun 30 '06 #6
> I don't believe that to be the case. My understanding is that because
the vtable for each instance of a particular concrete class is the
same, and all the information necessary to construct it is available at
compile time, virtual dispatch overhead is independent of inheritance
depth -- basically it's an extra pointer deref, period (plus an
addition op for indexing? I'm not 100% sure). The only thing that has
to be done at runtime is to determine, by looking at the hidden vtable
pointer in each polymorphic class instance, which vtable to use.

Luke


Ya that's true. But you are talking about virtual function, and I was
talking about dynamic_cast.

Virtual function by its own is a mere O(0) operation. I was talking
about the algorithm inside that possible virtual function that is O(n)
by its simplest.

Regards,
Ben
Jul 1 '06 #7
> Thanks Ben. As of now, instead of dynamic_cast, we have just put
virtual int getSize() { return sizeof(*this);}
in all the classes of the hierarchy (some 4-5). And in myFunc, we did
ptr + i*ptr->getSize()
instead of using ptr[i]

I know this is not very elegant and especially if someone adds a new
class, he _has_ to override this method. But this is some old legacy
code and I dont want to change a lot here. And am pretty sure, there
wont be new classes added.

Thanks,
Vikram


Wow, I didn't know you have an array to BaseC instead of an array to
BaseC*. How did you convert DerivedC[], say, to BaseC[]?

There is a design problem here: why do you have an array to BaseC (not
BaseC*) instead of an array to DerivedC?

As with the legacy code, if you 1) are so confident that the BaseC[]
array is indeed a DerivedC array, and 2)want to bypass the runtime type
checking, then why don't you just use static_cast?

void myFunc( baseC ptr[], int length) {
DerivedC* ptr2 = static_cast<DerivedC*>(&ptr[0]);

for (int i=0; i<length; i++)
ptr2[i].someField = somevalue;
}

Regards,
Ben
Jul 1 '06 #8
benben wrote:
I don't believe that to be the case. My understanding is that because
the vtable for each instance of a particular concrete class is the
same, and all the information necessary to construct it is available at
compile time, virtual dispatch overhead is independent of inheritance
depth -- basically it's an extra pointer deref, period (plus an
addition op for indexing? I'm not 100% sure). The only thing that has
to be done at runtime is to determine, by looking at the hidden vtable
pointer in each polymorphic class instance, which vtable to use.

Luke

Ya that's true. But you are talking about virtual function, and I was
talking about dynamic_cast.

Virtual function by its own is a mere O(0) operation.


O(1). There are no O(0) operations. Review the formal definition
(e.g. on Wikipedia) if you are unclear as to why.
I was talking
about the algorithm inside that possible virtual function that is O(n)
by its simplest.


By what rationale? The O(n) exploration of the inheritance hierarchy
necessary to determine the validity of a dynamic_cast can be, and
surely is in any reasonable implementation, done at compile time. I
seriously doubt there's any reason the runtime operation can't be O(1).

Luke

Jul 1 '06 #9
benben schrieb:
>Thanks Ben. As of now, instead of dynamic_cast, we have just put
virtual int getSize() { return sizeof(*this);}
in all the classes of the hierarchy (some 4-5). And in myFunc, we did
ptr + i*ptr->getSize()
instead of using ptr[i]

I know this is not very elegant and especially if someone adds a new
class, he _has_ to override this method. But this is some old legacy
code and I dont want to change a lot here. And am pretty sure, there
wont be new classes added.
Thanks,
Vikram

Wow, I didn't know you have an array to BaseC instead of an array to
BaseC*. How did you convert DerivedC[], say, to BaseC[]?

There is a design problem here: why do you have an array to BaseC (not
BaseC*) instead of an array to DerivedC?

As with the legacy code, if you 1) are so confident that the BaseC[]
array is indeed a DerivedC array, and 2)want to bypass the runtime type
checking, then why don't you just use static_cast?

void myFunc( baseC ptr[], int length) {
DerivedC* ptr2 = static_cast<DerivedC*>(&ptr[0]);

for (int i=0; i<length; i++)
ptr2[i].someField = somevalue;
}
Because he wants to use this function polymorphically with baseC[] and
DericedC[]?

Thomas
Jul 1 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Rick | last post by:
Hi, I wrote a few classes recently and am writing a small GC implementation for C++. I will be implementing my own gc_ptr type maintain a list where I'll store pointers to allocated memory. I...
2
by: shishir | last post by:
Please consider the following //file test.cpp #include <iostream> int main() { int x; try { throw x;
6
by: Kleidemos | last post by:
If I implement a simple RTTI system, more simple than C++ RTTI system for my program and this system is plus or minus: #define DEF_RTTI_BASE(name) virtual inline const char *Name(){ return...
9
by: Agoston Bejo | last post by:
Hello there, I would like to know what overheads there are to think of when using RTTI. I understand that enabling RTTI increases the sizes of the classes, but not the objects themselves. This...
4
by: Jim Strathmeyer | last post by:
I'm writing code with a whole lot of inheritance and am finding myself getting an object's type a lot. I do this by having a enumerated data member in the base class, and setting it in the derived...
2
by: denny | last post by:
Hey all, I know that dynamic_cast<> takes some time, but , for instance, is there a memoy cost associated in with it? Does it have to maintain a table in memory, thus bloating the runtime ram...
3
by: Steven T. Hatton | last post by:
I'm trying to work out a design for dynamically determining file types, and for generating new files of a given type. I'm curious to know what others think of my current strategy. Is it "so...
5
by: dotNeter | last post by:
I'm studying the RTTI, and my current work is concern for how to get the self-defined type at runtime, that's exactly what the RTTI does. I mean, in my application, I built several self-defined...
2
by: Chameleon | last post by:
I know than dynamic_cast check string name of derived to base class and if one of them match, return the pointer of that object or else zero. I suppose, I dynamic_cast instead of strings, checks...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.