RTTI
Run Time Type Information is also one of the core features of conventional C++. It allows retrieval of the object type information (using typeid operator) as well as checking the inheritance hierarchy (using dynamic_cast) at run time. The RTTI is available only when there is a polymorphic behaviour, i.e. the classes have at least one virtual function.
Let's try to analyse the generated code when RTTI is in use. The test_cpp_rtti application in embxx_on_rpi project contains the code listed below.
Somewhere in *.cpp file:
Somewhere in main
function:
Let's open the listing file and see what's going on in there. The address of SomeClass::someFunc()
seems to be 0x8300
:
The virtual table for SomeClass
class must be somewhere in .rodata
section and contain address of SomeClass::someFunc()
, i.e. it must have 0x8300 value inside:
It is visible that compiler added some more entries to the virtual table in addition to the single virtual function we implemented. The address 0x9c04 is also located in .rodata
section. It is some type related table:
Both 0x9c28 and 0x9bf8 are addresses in .rodata*
section(s). The 0x9bf8 address seems to contain some data:
After a closer look we may decode this data to be "9SomeClass" ascii string.
Address 0x9c28 is in the middle of some type related information table:
How these tables are used by the compiler is of little interest to us. What is interesting is a code size overhead. Lets check the size of the binary image. With my compiler it is a bit more than 13KB.
For some bare metal platforms it may be undesirable or even impossible to have this amount of extra binary code added to the binary image. The GNU compiler (gcc
) provides an ability to disable RTTI by using -no-rtti
option. Let's check the virtual table of SomeClass
class when this option is used:
The virtual table looks much simpler now with single pointer to the SomeClass::someFunc()
virtual function. There is no extra code size overhead needed to maintain type information. If the application above is compiled without exceptions (using -fno-exceptions
and -fno-unwind-tables
) as well as without RTTI support (using -no-rtti
) the binary image size will be about 1.3KB which is much better.
However, if -no-rtti
option is used, the compiler won't allow usage of typeid operator as well as dynamic_cast. In this case the developer needs to come up with other solutions to differentiate between objects of different types (but having the same 'ancestor') at run time. There are multiple idioms that can be used, such as using simple C-like approach of switch
-ing on some type enumerator member, or using polymorphic behaviour of the objects to perform double dispatch.
CONCLUSION: Disabling Run Time Type Information (RTTI) in addition to eliminating exception handling is very common in bare metal C++ development. It allows to save about 10KB of space overhead in final binary image.
Last updated