Efficient Use of C++ in Embedded Systems

Those of you planning to begin a project in using C++, hopefully using the MPLAB XC32++ compiler or the chipKIT platform, already know about the object-oriented programming concept of polymorphism. Essential to polymorphism is the concept of a virtual method, a method whose behavior can be overridden within an inheriting class by a method with the same signature.

Virtual methods are implemented using a virtual method table (vtable). The compiler creates a vtable for each class. When an object is created, a pointer to this table is added as a hidden member of the object. The compiler also generates code to initialize the vpointers of its objects to the address of the corresponding vtable. When designing your classes for your embedded application, you will want to keep the extra overhead of the vtable in mind.

Along the same lines, as an embedded-systems developer, you may be surprised by the overhead required by a pure virtual method, since it has no implementation and can therefore never be called directly. Well, the compiler generates error-handling code to handle the case where a pure virtual function is called. In the current XC32 v1.20 compiler release, when a pure virtual method is called, an error message is printed and a C++ exception is thrown, bringing in a fairly large amount of code that should never be executed. While the error handling is useful, we plan to look into simplifying it in future compiler releases to reduce the overhead. For now, you will find that avoiding a pure virtual method will help keep your code size down.

A pure virtual method assigns the function the value 0 rather than providing an implementation. For example:

class Base
{
public:
const char* SayHi() { return "Hi"; } // a normal non-virtual method
virtual const char* GetName() { return "Base"; } // a normal virtual method
virtual int GetValue() = 0; // a pure virtual method
};

To avoid the extra overhead, provide a default implementation like this:

class Base
{
public:
const char* SayHi() { return "Hi"; } // a normal non-virtual method
virtual const char* GetName() { return "Base"; } // a normal virtual method
virtual int GetValue() { while(1); /* Error */ } // a normal virtual method
};

Another hidden consumer of Flash space to look out for is Run-Time Type Information (RTTI). This C++ mechanism exposes information about an object’s data type at runtime. The dynamic_cast<> operation and typeid operator are part of RTTI. When this feature is enabled, additional the type information gets stored in Flash and can consume space even when the application does not use it. When you’re not using RTTI, be sure to disable it in your project settings (-fno-rtti). This compiler option can be added to the chipKIT IDE (MPIDE) default compiler option in <install_dir>/hardware/pic32/platforms.txt

C++ exception handling also causes additional code to be generated. Although exceptions provide a way to react to exceptional circumstances (like runtime errors) in an application, they come at a fairly substantial code and data memory cost. When your application doesn’t require exception support, you can disable it in your project settings (-fno-exceptions). This option is specified by default when the chipKIT IDE (MPIDE) invokes the chipKIT compiler.

[ Thanks to Jason Kajita for this helpful information ]
VN:F [1.9.22_1171]
Rating: 9.3/10 (4 votes cast)
Efficient Use of C++ in Embedded Systems, 9.3 out of 10 based on 4 ratings

One thought on “Efficient Use of C++ in Embedded Systems”

  1. Thank you for this.
    I have been trying to work with a porting a 3rd party Arduino library and was pulling my hair out trying to get some idea of where all my prog flash was going.
    After finding this article I found and modified a single pure virtual method with your suggested default implementation and reduced my sketch size from over 111Kb down to 44kb. Perfect!
    I think it might be a good idea to add a clear note about the effect of these pure virtual methods in the “working with libraries” section of the Chipkit site as I’m sure others have had similar problems and getting memory usage information out of MPIDE is not the easiest of things…
    Thanks again.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: +1 (from 1 vote)

Comments are closed.