Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest RTTI implementation for C++?

I'm trying to implement exception handling for an embedded OS and I'm stuck at how to detect the type of the thrown "exception" (to select the appropriate handler).

The saving and restoring context parts of the exception handling are already done, but I can't have specific handles since I can't detect the type of the thrown 'exception'. The standard RTTI implementation of c++ is too dependent of other libraries and for that reason I'm currently considering it unavailable.

Considering that my target is an embedded system and for that reason I can't create much code, what is the smallest implementation of "Runtime Type Information" I can get (or make)?

-- Edit --

I'm not working on the compiler, It's an ia32-g++.

like image 931
freitass Avatar asked Jul 03 '09 21:07

freitass


People also ask

What is RTTI in C?

Run-time type information (RTTI) is a mechanism that allows the type of an object to be determined during program execution. RTTI was added to the C++ language because many vendors of class libraries were implementing this functionality themselves. This caused incompatibilities between libraries.

How is RTTI implemented?

Typically, RTTI is implemented by placing an additional pointer in a class s virtual function table. This pointer points to the type_info structure for that particular type.

Which class is used in RTTI?

RTTI is intended for use only with polymorphic classes.

Why is RTTI a necessary feature of C++?

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.


2 Answers

As you're working in an embedded environment, you presumably favour extremely minimal solutions and you can take advantage of non-standard or non-portable facts about your compiler.

If a class is polymorphic (has at least one virtual function of its own) in C++, it probably has a pointer to a vtable embedded somewhere in it. It may be that the vtable pointer appears at the beginning of the object's layout in memory.

This is true of many compilers, ones that use the C++ ABI - a related SO question here.

If so, you might be able to get at the vtable like this:

void *get_vtable(void *obj)
{
    return *(reinterpret_cast<void **>(obj));
}

Then you can compare the vtables of two pointers-to-objects to see if they point to the same type of object.

So a "type switch" (which is what catch basically is) would do something like this:

P p;
Q q;
if (get_vtable(caught) == get_vtable(&p))
{
    // it's a P...
}
else if (get_vtable(caught) == get_vtable(&q))
{
    // it's a Q...
}

You could hide that pattern in a CATCH macro.

Important point - if you derive a class from a base, but the derived class does not override any virtual functions or add any new virtual functions, then the compiler could conceivably reuse the base class's vtable for the derived class. This means that in order to distinguish between two exception types, they must each override a virtual function, to ensure that they have their own vtables.

Note that this is only a tiny fraction of what exception handling involves. There is also the small matter of unwinding the stack! You need to call the destructors of all objects on the stack when you jump to the handler. It's not just a matter of doing setjmp/longjmp.

like image 87
Daniel Earwicker Avatar answered Sep 21 '22 23:09

Daniel Earwicker


The simplest RTTI I can think of is to derive all classes from a common base that have a pure virtual "GetType()" function. Either get it to return a string or create a huge enum with all the types in it. Its pretty simple, its quick and has low memory overhead. Not particularly flexible, however.

like image 33
Goz Avatar answered Sep 19 '22 23:09

Goz