Why is RTTI (Runtime Type Information) necessary?
RTTI, Run-Time Type Information, introduces a [mild] form of reflection for C++.
It allows to know for example the type of a super class, hence allowing to handle an heterogeneous collection of objects which are all derived from the same base type. in ways that are specific to the individual super-classes. (Say you have an array of "Vehicle" objects and need to deal differently with the "Truck" objects found amid the array).
The question whether RTTI is necessary is however an open one. Story has it that Bjarne Stroustrup purposefully excluded this feature from the original C++ specification, by fear that it would be misused.
There are indeed opportunities to overuse/misuse reflection features, and this may have been even more of a factor when C++ was initially introduced because there wasn't such a OOP culture in the mainstream programmer community.
This said, with a more OOP savvy community, with the effective demonstration of all the good things reflection can do (eg. with languages such as Java or C#) and with the fancy design patterns in use nowadays, I strongly believe that RTTI and reflection features at large are very important even if sometimes misused.
boost::any
. –
Bullheaded I can think of exactly one case when it would be appropriate to use RTTI, and it doesn't even work.
It is fairly common for C-compatible APIs which perform callbacks to provide a user-defined void* to communicate a state structure back to the caller. When calling such an API from C++, it is quite common to pass the this pointer through said void* argument. From the callback, one might want to invoke virtual functions on the passed pointer.
In some cases when the callback parameters are insecure (such as LPARAM of a Windows message), it is obviously desirable to validate the pointer before using it for a virtual call, by checking the hidden vfptr. dynamic_cast
is the natural way to do this, but results in undefined behavior exactly when the object is invalid (IIRC, it is undefined behavior if the pointer is to anything except an object with a virtual table). So RTTI is utterly useless for preventing a shatter attack in this way.
Feel free to present any other valid use cases for RTTI, cause I'm totally unconvinced.
EDIT: boost::any
got mentioned. As far as boost::any
is concerned, you can disable RTTI and use the following typeid implementation:
typedef const void* typeinfo_nonrtti;
template <typename T> typeinfo_nonrtti typeid_nonrtti();
template <typename T> class typeinfo_nonrtti_helper
{
friend typeinfo_nonrtti typeid_nonrtti<T>();
static char unique;
};
template <typename T> char typeinfo_nonrtti_helper<T>::unique;
template <typename T>
typeinfo_nonrtti typeid_nonrtti() { return &typeinfo_nonrtti_helper<T>::unique; }
boost::any
. :) –
Bullheaded holder<ValueType>
template. If it is RTTI, then you're in serious trouble because any_cast
does an equality match based on the typeid
, not a subclass match, so it would be effectively impossible to get the value back out (you'd have to any_cast
to the exact runtime type of the object, not the type you put in, if the type is polymorphic). I've never used boost::any
and based on a cursory examination of the source, never will. Too fragile. –
Millicentmillie boost::any
uses typeid(ValueType)
, not typeid(value)
. Therefore it's purely compile-time type information even if the type is polymorphic. Completely useless, you can get the same effect without typeid
or any use of RTTI. –
Millicentmillie boost::any
. –
Millicentmillie static
. –
Millicentmillie © 2022 - 2024 — McMap. All rights reserved.