Recently I was asked whether to use C or C++ for an embedded project. Let’s assume a sizeable project with an ARM7-based microcontroller and roughly 16KB of RAM. Here is my answer, and I hope it’s useful for you.
One good reason to go with C++ might be that you have a ready team of programmers who are already fluent in it. This would be a strong pull, but if they are not fluent in the embedded world particularly, then this article may help them choose a subset of C++ suitable for an embedded environment.
As the guy said, C makes it easy for you to shoot yourself in the foot, but C++, being much more complex and powerful, allows you to blow your whole leg off. This is true especially in embedded situations.
If you’ve only used C for embedded projects, you’ll be able to get started and into the project much more quickly if you stick with C, and other people could take over more easily. You won’t spend time learning the ins and outs of C++.
C has the advantage of being very direct and “what you see is what you get”. For example, in C this line of code adds two numbers together:
int x = y + z;
But in C++ a very similar-looking line:
MyType x = y + z;
This calls a constructor (which could do anything), calls the + operator of y’s class which (if overloaded) could do anything, possibly throws an exception, possibly allocates memory, etc. You just don’t know, unless your coding style guide lays down the law about what you can and can’t do (more on that soon).
On the other hand, there are definitely some good features in C++’s favour that make programming better, especially for larger projects. Classes, namespaces, templates, scoping … but the language has a ton of powerful features as well as quirks, so when you’re embedding C++ you have to choose a subset of the language and stick with it.
For instance, for embedding C++ in an ARM7-sized processor, you might come up with a list something like:
- Use function overloading, default arguments, and references.
- Use namespaces and classes.
- Use templates for specific things X, Y, and Z.
- Use RAII and scoping for things like allocation, locking, etc.
- Use inheritance and virtual functions, but sparingly, only as required.
- Use C++ style casts, but not
- Don’t use
new, exception on boot-up. Don’t use
delete. Use storage pools and “placement new” where appropriate.
- Don’t use the STL (Standard Template Library).
- Don’t use exceptions or run-time type information.
- Don’t do operator overloading (far too many quirks and memory management problems).
- Don’t use friends or friend classes.
If you haven’t used C++ before, you’ll definitely want to learn it before getting too far in. Following some links in my C++ blog articles may be helpful here:
- C++ for C programmers, part 1 of 2 — the non-object oriented features
- C++ for C programmers, part 2 of 2 — the OO features
- RAII, AC/DC, and the “with” statement
- Protothreads and C++ — protothreads (lightweight pseudo-threads) are useful for embedded systems
That said, you can’t learn it just by reading about it, so you need to start coding.
In conclusion, for a small embedded job I’d pick C first for its simplicity, directness, and the fact more people know it. For a larger project, I’d pick C++ — it can make embedded life nicer, but only if you carefully choose a subset and have a good coding standard.
- Abstraction and the C++ machine model [PDF] — a paper by the creator of C++ on using C++ in embedded systems
- C++ for Embedded: Dos and Don’ts [PDF] — an article with some good points above moving from C to C++ for embedded code
- Linus Torvalds’ rant on why Linux isn’t written in C++ — some good points, but not a level-headed discussion of the topic
20 January 2011 by Ben 5 comments