bnpph wrote:P.S.
I like your forums.
Haha, welcome to a place where men can bitch each other out over code and still respect each other enough to grab a beer later.
bnpph wrote:GyroVorbis wrote:First of all that typeid() grows linearly with the length of the class name. It also grows linearly with the depth of the inheritance tree (since a class must now be aware of its ancestry at run-time).
You sure this is correct?
I probably should have elaborated here. I worded it fairly wonkily.
RTTI data is stored within a class's vtable as a pointer to an RTTI metadata object (called type_info). This metadata object must store the name of the class so at very least it is growing linearly by a byte in size with each character of the class name.
Along with this class-name overhead, the vtables themselves must now store "offsets" to the vtables of their parent classes. In a normal class inheriting from a virtual class WITHOUT RTTI, the only association the child's vtable even had with the parent is a few duplicate entries for virtual methods that were not overwritten. With RTTI, you have a new inter-vtable dependency since the dynamic_cast<> operator must now be able to jump from a child object's vtable to a parent object's vtable to inspect its type metadata object during the cast.
Once again, not only does the size of the vtable expand linearly with each virtual base class inherited, but the time complexity of the dynamic_cast<> operation literally becomes a tree traversal of linear time complexity for a failed cast (the entire tree must be checked).
bnpph wrote:I think it's still dynamic, dunno though.
Oops. I meant "dynamic" in the sense of being aware of a hierarchy. Observe:
Code: Select all
class A { virtual ... };
class B: public A { virtual ... };
[..]
if(typeid(A) == typeid(B)) {
//This is never going to be true. You have to suffer the consequences of a dynamic_cast for this behavior...
}
In a "type" sense, you are correct, though. In the above example, if we had:
The
static type of "a" would be "A," while the
dynamic type of "a" would be "B."
bnpph wrote:Anyway, RTTI is standard C++, and so I don't think it should be shunned and called an "extension."
"Standard" is relative term. I feel like you're under a misconception as to how standard this feature actually is. Standard in that the compiler should
support it is different than being a feature that is a standard part of the language. STL is more "standard" than RTTI, and it's a separate library.
Most compilers disable RTTI by default. ALL compilers at least have options for it. MANY compilers (on embedded platforms) don't even implement RTTI. It might be ANSI standard "now" to "support" it, but it sure as hell isn't to allow it by default. What compiler are you using? You were able to use typeid() out of the box?
If all of the overhead I presented STILL hasn't convinced you (don't make me count clock cycles), then what about these?
RTTI should only be used sparingly in C++ programs. There are several reasons for this. Most importantly, other language mechanisms such as polymorphism and templates are almost always superior to RTTI. As with everything, there are exceptions, but the usual rule concerning RTTI is more or less the same as with goto statements. Do not use it as a shortcut around proper, more robust design. Only use RTTI if you have a very good reason to do so and only use it if you know what you are doing.
http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI
Call the throw operator only when you want notify a user of the failure of the current command.
The raising of an exception has a very high cost, compared to a function call. It is thousands of processor cycles. If you perform this operation only when a message is displayed on the user interface or written into a log file, you have the guarantee that it will not be performed too often without notice.
Instead, if exception raising is performed for algorithmic purposes, even if such operation is initially thought to be performed rarely, it may end up to be performed too frequently.
http://en.wikibooks.org/wiki/Optimizing ... g_features
Bjarne Stroustrup (Father of C++) originally didn't want to include RTTI with the language.
http://www2.research.att.com/~bs/hopl2.pdf
AND LASTLY, observe the structure of the vtable itself. Each instance of a virtual class has a __dptr. Where does this point in the vtable? To the
first virtual function entry. It then proceeds to grow in a
downward direction. Where does this additional metadata (type_info and parent vtable offsets) wind up getting stored in the vtable? ABOVE the actual vtable pointer. Optional/additional metadata in the vtable grows
upward (and is indexed with a negative offset) whereas standard vtable data grows downward. Even the design of the vtable itself implies that additional metadata overhead is not standard.
http://www.codesourcery.com/public/cxx- ... le-ex.html
^ That's actually a REALLY kickass article from HP comparing methods for handling additional offset/vtable metadata involved with virtual inheritance along with RTTI.