views:

1612

answers:

11

I am writing a program, more specifically a bootloader, for an embedded system. I am going to use a C library to interact with some of the hardware components and I have the choice of writing it either in C or C++. Is there any reason I should choose one over the other? I do not need the object oriented features of C++ but it does have a stronger type system. Could it have other language features that would make the program more robust? I know some people avoid C++ because it can (but not always) generate large firmware images.

+10  A: 

If you don't need to use Object Orientation, use C. Simple choice there. Its simpler and easier, whilst accomplishing the same task.

Some die hards will disagree, but OO is what makes C++ > C, and vice versa in a lot of circumstances.

Kyle Rozendo
you can write OO in C too, in fact in almost any language, in the sense that you collect data in a structure and write methods operating on it; there it ends though.
stijn
yea, but i think kyle is aware of that. a well gauged reply, i'm a fan of both c and c++
Matt Joiner
You can write OO in any language, you just wont get syntax errors when you use an inappropriate method on a structure.
James Anderson
Also, OO is what makes C++ < C in a lot of circumstances.
Jurily
Yeap, of course. Therein lies the "some die hards" comment ;)
Kyle Rozendo
"You can write OO in any language" - OOP is not about "using methods on a structure", it is about having **dynamically bound** methods. Implementing a vtable mechanism in plain C on your own is simply not justified if you already have it in C++.
Groo
I have to disagree with this one. OOP support is probably the *least* relevant reason to prefer C++, especially in an embedded setting. As Al's answer shows, C++ contains a large number of improvements that just yield better, more robust code than C, but aren't in any way specific to OOP.
jalf
I've dealt with OO C (and, yes, it did have inheritance and I think polymorphism). I'd almost rather use COBOL.
David Thornley
"die hards" is a bit argumentative, couldn't you just say "some will disagree"?
MarkJ
I could have, but it is my belief that it is in fact the die hards that would disagree. It is also only argumentative if an argument is created. If you do however feel strongly about it, add another comment and I will change it.
Kyle Rozendo
A: 

For such a specific task as a bootloader I would definitely not use C++. I think the standard c++ library is at least a couple of MB, not something you want in a bootloader. Go with C.

Puppe
+1 over here, must agree.
Tzury Bar Yochay
-1: Over simplification; programming in C++ is not the same as using the standard library and many benefits can be gained from using C++ for code structure and extra type checking without using the full library. This won't add much to the code size.
Al
not really going to be using standard libraries in a bootloader (one would assume given the embedded tag). i don't think this is the main reason you'd use C over C++ in this case.
Matt Joiner
Yup - I have written an actual bootloader for an ARM-based device, and it doesn't even use the _C_ standard library. `malloc()` ? Are you kidding? We'd just include "memory_layout.h"
MSalters
+6  A: 

Write programs in C is not the same as writing it in C++. If you know how to do it only in C++, then your choice is C++. For writing bootloader it will be better to minimize code, so you probably will have to disable standard C++ library. If you know how to write in C then you should use C — it is more common choice for such kind of tasks.

Kirill V. Lyadvinsky
+10  A: 

For a boot-loader the obvious choice is C, especially on an embedded system. The generated code will need to be close to the metal, and very easy to debug, likely by dropping into assembly, which quickly becomes difficult without care in C++. Also C tool-chains are far more ubiquitous than C++ tool-chains, allowing your boot-loader to be used on more platforms. Lastly, generated binaries are typically smaller, and use less memory when written C style.

Matt Joiner
+2  A: 

The C language is substantially easier to parse than C++. This means a program that is both valid C and valid C++ will compile faster as a C program. Probably not a major concern, but it is just another reason why C++ is probably overkill.

Artelius
+21  A: 

This isn't a particularly straightforward question to answer. It depends on a number of factors including:

  • How you prefer to layout your code.
  • Whether there's a C++ compiler available for your target (and any other targets you may wish to use the bootloader on).
  • How critical the code size is for your application (we're talking about 10% extra maybe, not MB as suggested by another answer).

Personally, I really like classes as a way of laying out my code. Even when writing C code, I'll tend to keep everything in modular files with file-scope static functions "simulating" member functions and (a few) file-scope static variables to "simulate" member variables. Having said that, most of my existing embedded projects (all of which are relatively small scale, up to a maximum of 128kB flash including bootloader, but usually less) have tended to be written in C. Now that I have a C++ compiler though, I'm certainly considering moving to C++.

There are considerable benefits to C++ from simply using references, overloading and templates, even if you don't go as far as classes. Certainly, I'd stop short of using a lot of more advanced features, including the use of dynamic memory allocation (new). Then again, I'd avoid dynamic memory allocation (malloc etc) in embedded C as well if possible.

If you have a C++ compiler (even if it's only g++), it is worth running your code through it just for the additional type checking so that you can reduce the number of problems in your code. The C++ compiler can pick up on a few things that even static analysis tools won't spot.

For a good discussion on many invalid reasons people reject C++, see Dan Saks' article on Embedded.com.

Al
Good answer. I would probably make the choice dependent on the target. If it's anything bigger than a 8-Bit µC, I'd try to stick with C++. I've learned to hate C++, but I think it can give you same benefits over using C if you know what you're doing. As always, a very good advice:Know what you're doing and why.
ziggystar
What do you mean "even if it's only g++"? It's a pretty good C++ compiler. Is there some specific reason to avoid it in this case?Anyway, good answer, and I agree. Many of C++'s features (like references and templates) can be used simply to write safer, more robust code, with no runtime cost in either memory or speed. Of course, C++ also has a number of features that you should be very careful with in an embedded setting. But they can be avoided, like yo usay.
jalf
I agree that using C++ as a 'better C" is a nice idea for something like this. But I also find myself in a bit of a quandary when I've tried to do that in the past: trying to use C++ in this way while avoiding dynamic memory. So much of the useful stuff in C++ depends on dynamic memory that I find myself in a constant struggle of reinventing things that I want to use from C++ libraries and techniques that it's often just simpler to say - this project is using C, full-stop.
Michael Burr
@jalf: Sorry, I should have worded that better. When I said "even if it's only g++", I meant: "even if you don't bother finding one (or can't find one) for your embedded platform and just pick a freely available PC one like g++".
Al
Polymorphism depends on dynamically allocated memory, as does much of the standard library (like container classes and strings). Classes themselves don't, nor templates, and C++ does have a stricter type system. There's considerable advantages to C++.
David Thornley
@David: one small correction - polymorphism doesn't depend on dynamic memory. Other nice techniques used in a lot of C++ code that require dynamic memory: shared_pointer<>, pimpl. Pimpl isn't too hard to do without, though.shared_pointer<> can be written to use a fixed block allocation area for the contained pointer and ref count, but that's the kind of thing I'm talking about when I say you end up having to reimplement things.
Michael Burr
"file-scope static [functions/variables] to simulate member [functions/variables]" ?! What's with the "static" ?!
sellibitze
@sellibitze: From Wikipedia: "Static global variables are declared as "static" at the top level of a source file. Such variables are not visible outside the source file ("file scope"), unlike variables declared as "extern"." See http://en.wikipedia.org/wiki/Static_variable
Al
+6  A: 

I would use C unless there is a specific reason to use C++. For a Bootloader you are not really going to need OO.

Use the simplest tool that will accomplish the job.

Gerhard
amen to using the simplest tool for the job. i think ill have to upvote this! :D
Matt Joiner
A: 

Use C with µClibc. It will make your code simpler and reduce its footprint. Can be found in: www.uclibc.org.

eyalm
Have a link to where to find this library?
spoulson
+3  A: 

Most of the previous answers assume that your bootloader is small and simple which is typically the case; however, if it becomes more complex (i.e. you need to be able to load from an Ethernet port, a USB port, or a serial port...you need to validate the code that is being loaded before you wipe out your existing code, etc.) you may want to consider C++.

I have also found that the bootloader and the application typically share some amount of common code so you may also want to consider using the same language as your application to facilitate the code sharing.

semaj
+1 Good points, especially the bit about code sharing.
Al
A: 

No matter what route you go, for heaven's sake please use the C++ compiler.

Ether
A: 

Go with C++ and objchoose what language features you need. You still have full control of the output object code as long as you understand the C++ abstractions that you're using.

Use of OO can still run well if you avoid the use of virtual functions. Avoid immutable object types that require a lot of copying in order to pass values, like std::string. But, you can still use features like templates without any real impact on runtime performance.

spoulson