Reputation: 105
Virtual methods work without RTTI, shouldn't that mean there's enough data around at runtime to figure out which class it is?
(i want to find out how i can downcast and then check if it was a pointer to the right type. i can't modify the classes involved or turn on RTTI, though.)
Upvotes: 4
Views: 1718
Reputation: 145269
Type information, identification of dynamic type, is not needed for virtual function dispatch.
Virtual function dispatch is usually implemented via a vtable pointer in each object, where that pointer points to a type-specific table of pointers to function implementations (the "vtable").
Type information is needed for dynamic_cast
and typeid
.
In the case of typeid
, which returns type information, that information must necessarily exist somewhere in the executable. When you turn off storing of the information, it's not there to be retrieved. But what about dynamic_cast
?
In the simplest case dynamic_cast
is a downcast from some base type reference, to a derived type reference, a D&
. The derived type needs not be the object's most derived type. Hence, for the now universal vtable scheme for dynamic dispatch, the object's vtable pointer needs not point to the D
type's vtable, and therefore doesn't provide a simple check of success.
Still for a language restricted to single inheritance the pure downcast case can be solved by using the vtables themselves as type identifiers, by searching up the (single) inheritance chain via parent pointers in the vtables.
With multiple inheritance in the picture things get complicated. As an example, if class Derived
inherits from both Base1
and Base2
, where both are polymorphic, then the Derived
class' vtable can't simply extend Base1
's vtable and simply extend Base2
's vtable. And so if, say, the Derived
vtable extends Base1
, then when one reinterprets a Derived*
as a Base2*
, the pointed to object's Derived
vtable pointer will no longer work as a pointer to the statically known class' vtable.
And so one consequence is that conversion to base type reference, in the presence of multiple inheritance, cannot always be a simple reinterpretation of the pointer type -- the pointer value may have to be adjusted.
How to do this is so non-obvious that Bjarne Stroustrup had to prove to himself that a vtable scheme for multiple inheritance could be implemented, before adding multiple inheritance to the language.
I do not know how current compilers deal with it, in particular for dynamic_cast
, but since simple vtable parent pointers do not work for multiple inheritance, logically the compilers can't do it via that mechanism: some extra support data structures, RTTI information, are needed.
" i want to find out how i can downcast and then check if it was a pointer to the right type. i can't modify the classes involved or turn on RTTI, though.
If you can't change the code or turn on RTTI you generally can't obtain the required information.
In the special case where you control all object instantiations you could in principle maintain a separate per-object map of type information, but it would be extremely inefficient.
Upvotes: 5
Reputation: 15144
If compilers inserted enough data at runtime to make dynamic_cast
work, then they would also have inserted enough for RTTI to work. If you can dynamic_cast
a reference to another type, you can check whether it’s the same type or a descendant of another type. Therefore, this would be the same as simply turning RTTI on by default.
As an example of why a compiler might want to turn this off for efficiency, what happens if you have a derived class that doesn’t override any of its parents’ virtual functions? The compiler might want it to simply re-use the same virtual function table. It also doesn’t need to track base and derived relations to do function dispatch.
Upvotes: 0