16

I am developing an application for embedded Linux (ARM). It will execute 500 times/sec, therefore speed is important. I would prefer to use C++ but I am afraid it will be slower than C even if I avoid fancy features like virtual functions. Is there a reason to use C or it's just as fine to write in C++?

  • 8
    Virtual function is not one of the things you should be avoiding. To implement the same functionality in C manually will not be faster than the compiler generated version, and the C++ compiler is good at optimizing it away when not needed. – Martin York Feb 28 '11 at 20:00
  • 1
    @Martin's right. Virtual functions only cost one or two instructions to call, and if that's really what you need you'd have to do it anyway in C. – Mike Dunlavey Feb 28 '11 at 20:44
  • Some interesting related reading here: http://stackoverflow.com/questions/2039444/why-are-drivers-and-firmwares-almost-always-written-in-c-or-asm-and-not-c/2039645#2039645 – Emile Cormier Feb 28 '11 at 20:54
  • 2
    Try both C and C++, then measure the resulting binaries on the embedded device. If you don't want to write 2 versions of the application, just use the language you're more comfortable with (C++). – pmg Feb 28 '11 at 21:19

8 Answers8

18

C++ in general suffers no run time penalty over C - (except for a few things like RTTI).

Except in a few odd circumstances the compiler should be able to determine which virtual function to call at compile time and so add no overhead.

Edit: Ok with such a variety of compilers, CPUs, runtime libs, OSes there are some features of C++ that might create slower code, there are some features that might create faster code.

But can we all agree that C++ isn't automatically excluded from embedded use anymore ?

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • 1
    If you use C++ as "uglified C" (extra casts all over the place), then what you've said is true. But as soon as you start using anything that makes C++ "comfortable", there will be a lot more overhead that cannot be optimized out. – R.. GitHub STOP HELPING ICE Feb 28 '11 at 21:34
  • 2
    Virtual functions and templates should have zero cost. Exception are zero cost if not called on any decent compiler. Dynamic_cast will normally work without RTTI - with a few warnings. Code size might be an issue - but it depends what you mean by embedded of course – Martin Beckett Feb 28 '11 at 22:00
  • 2
    Exceptions have negative cost when you can remove the C error handling from the normal code flow. Optimizers can easily optimize for the non-exception case, but the don't know whether a C functions returns 0,1 or -1 in case of an error. – MSalters Mar 01 '11 at 08:43
  • I use C++11 and meta programming on an embedded ARM with 32K of flash! I have found that if you use a modern compiler (I use GCC 4.6) you can port C code to C++ and sometimes see size diminish. constexpr is an important tool. – odinthenerd Jun 28 '13 at 18:18
  • STL containers (implemented with templates) are in fact a huge win if you have any significant data structures in your code. The implementations are just as good as its possible to get - and likely better than ones you'd write yourself. You can also pool allocate if necessary. – marko Jun 28 '13 at 18:18
  • @MSalters +1 for this. Of course the comparison is often made to NOT writing error handling code at all, rather than correct (and tested? yeah...right..) error handling in C. RAII is a huge win in terms of correctness and verifiability. – marko Jun 28 '13 at 18:20
8

In C++ you have things like template metaprogramming that resolve in compile time several situations where C or any other procedural programming language would have to do in runtime.

I should say more. Template metaprogramming and some class inheritance tricks are really amazing. It can save you a lot of processing time that you'd spend otherwise by "ifing" and "switching".

This means that C++ can be actually faster than C if well conducted.

Obviously you can program "in C" using C++ and you'd have no penalty at all. If you're not too fond of C++ I'd advise you to do a "C on C++" or "C with C++ extensions" just to take vantage of C++ improvements, but the real advantage you'll have is by programming the C++ way. There you will see that C++ is, good part of times, or faster or cleaner than C or, at least as fast as.

Have no fear. Face C++. After the stdc++ (against libc) there will be almost no overhead in code size. If your application is from median to high in size, it will be diluted.

I use C++ from simple 8-bit ATmega to Marvell's ARM9, passing through AVR32 UC3 and Cortex-M3 and always find it profitable.

If you need specific advise in a given situation, feel free to ask.

j4x
  • 3,595
  • 3
  • 33
  • 64
  • 1
    That's the answer I was hoping for. C++ is much more fun to write even for simple things like being able to declare a var when you need it (as opposed to in the beginning of the block in C). And of cause I prefer class encapsulation vs C global functions. I hope to avoid dynamic memory allocation or anything exotic. – Gregory Khrapunovich Mar 03 '11 at 22:28
  • 1
    the advantages of C++ in the embedded world are far reaching. I have found __attribute((always_inline)) to be a godsend when making abstract interfaces compile into nothingness and only leaving stronger static checking of important stuff. – odinthenerd Jun 28 '13 at 18:12
7

The main reason for choosing C over C++ is size of the compiled binary, which can be a real restriction for embedded systems.

On performance, there's no measurable difference, if you use the language right. You can write slow C code just as easily as slow C++, as long as you're aware of the under-the-hood mechanisms of what you're writing you should be fine with either.

Erik
  • 88,732
  • 13
  • 198
  • 189
  • 6
    The size difference is negligible, provided that the C version is *functionally equivalent* to the C++ version. For example, if the C++ version uses inheritance, the C version must also code the equivalent, no short cuts. In my experience, size is not an issue. – Thomas Matthews Feb 28 '11 at 20:02
  • 4
    @Thomas: this is simply not true, because a lot of the library code that gets pulled in will have a huge superset of the required functionality, and no way for the linker to determine what parts can be left out. Static link a C hello world program with any sane C library (any of the BSDs, uClibc, Bionic, etc. - just not glibc whose stdio is essentially written in C++) and compare an equivalent static linked C++ program using iostream. – R.. GitHub STOP HELPING ICE Feb 28 '11 at 21:37
  • 2
    @R.. : if you select an appropriate implementation of libc, you should be fair and select an equally appropriate iostream. Dietmar Kuehl has proven (about 10 years ago) that Hello, World can be smaller in C++. Simple reason: the linker _can_ eliminate `operator< – MSalters Mar 01 '11 at 08:46
  • 1
    library size (theoretically speaking) may be an issue in some environments, but the original question mentions embedded Linux, so it is at least 32bit system and the operating system itself is large enough. So I'm doubdt that size matters in this case :) – user396672 Mar 01 '11 at 09:48
  • I'm currently building an embedded linux-based system where I chose to add more flash to the device in order to be able to include the c++ dynamic libraries. So at least for me, size was a real factor. – Erik Mar 01 '11 at 09:51
  • @Eric: You are right, it may happen if the whole system almost exactly fits the memory, I only suspict that such a case has relatively less probability (but not null, I agree) – user396672 Mar 01 '11 at 10:12
  • There are other embedded implementations than Linux or WinCE. Many of these compilers, Green Hills, Metaware, GNU, Arm, Intel, etc., design their libraries for small systems. Some even give you source code in case you need to specialize routines, such as `fwrite`. Remember that not all embedded platforms have consoles. – Thomas Matthews Mar 01 '11 at 17:47
  • @MSalters: The flaw in your argument is that floating point printing code is smaller than the minimal overhead you'll have from other things in iostream that can't be eliminated. (Exact floating point printing requires about 4-5k of code, and a non-exact but conformant implementation could probably be as small as 1.5-2k.) – R.. GitHub STOP HELPING ICE Mar 01 '11 at 20:48
  • @R..: Care to explain what this "non-reducable" overhead is? AFAICT it's a few bytes (Not even `sizeof(streambuf)+sizeof(std::cout)` because they can be combined.) – MSalters Mar 03 '11 at 12:01
  • @MSalters: Let's look at empirical values. Please show me a C++ "hello world" program using iostream whose binary (on x86, for the sake of being specific) is less than 16k and whose dirty memory at runtime is less than one page of stack plus one page of data. I'd love to be proven wrong, but if it's possible, certainly nobody has done it yet.... – R.. GitHub STOP HELPING ICE Mar 04 '11 at 00:12
  • Is that a complete C++ library implementation or a toy implementation to "prove a point"? If it's complete why isn't it being used? – R.. GitHub STOP HELPING ICE Mar 04 '11 at 15:42
  • My reason to not use it is, C++ is a silly "language". There is nothing that can be done in C++ that you can't do smaller, better and faster in C. The CPU has no instructions which come to life because you're using C++. If anything, you'll create the usual bug-laden hard-to-read mess that is a C++ program, versus getting closer to the metal and appreciating the fine art that is programming. Embedded programming almost always ends up requiring ASM too, and you'll find C++ pretty unfriendly there. Just my opinion based upon 30 years experience of embedded programming... –  Jun 28 '13 at 18:19
6

As long as you limit the features you use, you won't have much, if any, performance hit in C++ over C. The features you'll want to avoid include: exceptions, RTTI, and keep your class hierarchy as flat as possible (and use virtual functions sparingly).

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
3

C++ is fine as long as you have enough RAM and flash in your embedded system. The C++ runtime library (libstdc++) is big, and comes in addition to the C standard library (libc) even if you use C++ only.

GT.
  • 901
  • 1
  • 6
  • 10
  • 3
    In an embedded system, one only includes the libraries that are needed. Libraries used for a desktop version are usually a lot bigger and have no size correlation. Bogus about size issues. See my other post on SO. – Thomas Matthews Feb 28 '11 at 20:03
  • It is a bold move to argue against that fact that libstdc++ requires ram and flash ... – GT. Feb 28 '11 at 20:43
  • 2
    @Thomas: I'd like to see you find a way to make `libstdc++` small. `uClibc++` exists for a reason; sadly it's rather incomplete. – R.. GitHub STOP HELPING ICE Feb 28 '11 at 21:38
2

You can use C++ but be extra careful.

For size, keep a close eye on your linker map file. You can find it including tons of stuff you don't need, just from an innocent-looking declaration.

For speed, profile or random-pause often. It's super easy to do more news and deletes than you really need, especially with container classes, and be really careful with things like iterators. Often they're doing you un-asked-for favors.

You can step through the code at the assembly-language level to make sure it's only doing what you actually need, which should be about the same as the C code.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
1

I am using ARM9 board for hardware control and I am using both C and C++ Application in 500 Mhz board. It is up to you to use the language and how you implement your logic to implement the functionality. Because I have not found any problem running my Application over the day controlling the hardware.

While writting your program, carefully select your variable, check it against extra instruction/loop, initialization. also use Gcc optimization flag while compilation.

I have not any problem running my Qt Application and C program on 500 Mhz ARM 9 board.

SamKan
  • 81
  • 1
  • 9
1

The real key to size and speed efficient code, embedded or otherwise, is for the programmer to fully understand the implications of his orher decisions.

To an extent, C++ provides more opportunities where something expensive can look deceptively innocent. Equivalent functionality to C++ features often requires more ink on the page, which may lead to a little more contemplation of its potential expense. But it's by no means an absolute - C (and its libraries) has the risk of deceptively innocent expense too.

Ultimately there is no substitute for understanding what you have asked for in each line of code.

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117