Embedded software applications are most commonly written in C. For many
years, C++ has been seen as the natural successor and has found greater
acceptance, but the increase in its usage has been much slower than
anticipated.
There are a number of reasons for this. Firstly, embedded developers
are quite conservative and prefer to use solutions that are proven
rather than novel " "if it ain't
broke, don't fix it".
There is also the lesson of experience. Many developers have
attempted to use C++ for embedded applications and failed. Such
failures may sometimes be attributed to shortcomings in development
tools, but most often it is the inappropriate use of the language "
treating an embedded system like a desktop computer " that is to blame.
In this two part tutorial, an attempt is made to address some of
these issues, to give guidelines to the effective use of C++ for
embedded applications and to show that the language has some true
benefits to the embedded developer.
One of the key reasons why C++ has gained popularity in the
computing world in general is its history. Although it is a modern
language, with object oriented capabilities, it has backward
compatibility that makes its adoption " learning and application "
straightforward.
Figure 1 below gives some
insight into the evolution of the language. Later in this series we
will look at C/C++ compatibility in more detail.
 |
| Figure
1. The Genealogy of C++ |
Limitations of C
Although C is widely used, it has limitations, as it was not designed
for embedded applications or for projects of a scale that is now
commonplace. Key limitations include:
1) C is extremely powerful
and flexible and can therefore be dangerous.(It has low level capabilities - which are
useful for embedded " but also represent many pitfalls for the unwary.)
2) Programmers need to be
very methodical and disciplined
3) Programmers need to
understand how the program behaves at low and high levels (large
projects are thus hard to maintain)
4) Programmers need an
expert knowledge of the application
However, C++ has powerful object oriented capabilities which can
help significantly with addressing the limitations of C:
1) it encapsulates and hides
areas of high expertise from non-experts into "objects;" (A test case
will demonstrate the encapsulation of expertise later in Part 2 in this
series).
2) Objects can be used
intuitively by non-experts to implement conceptual designs at a
high-level
Language Overview
Like ANSI C, C++ features many enhancements to the original C language
in addition to its object oriented capabilities. C++ is not simply a
super-set of C, as the two languages evolved in parallel.
However, the language may be learned and applied incrementally, as
will be illustrated later in this paper. For the moment, here is a
summary of some of the useful language features:
1) Dynamic
memory allocation operators. The operators new and delete are
alternatives to the library functions malloc() and free() and lead to
more readable and less error-prone code.
2) Function
prototypes. Iintroduced
in C++ and adopted into ANSI C, their use is mandatory.
3) Function
parameter default values. A function may have default values for
trailing parameters to enhance code readability.
4) Reference parameters.
Function parameters may be passed by reference instead of by value
(copy). This gives the efficiency of using pointers without the great
potential for errors that results from their use. Here is a simple
example function:
void swap(int& a,
int& b)
{
int temp = a;
a = b;
b = temp;
}
4) Inline
functions. The code for a (small) function may be declared as
being inline " i.e. a copy of the actual code is included at each call
site. This improves the speed of execution, but may increase code size.
This may be achieved using the inline keyword or by including the code
in the body of a class definition. This is only advice to a compiler,
which will probably take account of current optimization settings.
5) Function
overloading. Multiple functions may be defined with the same
name. The compiler would distinguish between them by their unique
number/type of parameters. This results in more readable code, with
less contrived function naming.
6) Typesafe
linkage. In C++, all function names are "mangled" " their names
are modified to reflect parameter and returned data types. This enables
the linker to perform additional cross-module checking without being
required to "know" about C++. This is also the mechanism whereby
function overloading is implemented.