Author Topic: Which is better for embedded work: C or C++?  (Read 42199 times)

0 Members and 1 Guest are viewing this topic.

Offline andyturkTopic starter

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Which is better for embedded work: C or C++?
« on: May 21, 2013, 01:37:21 am »
There have been a couple of interesting discussions here on software topics. Assembly vs C is one, and the ISR discussion is interesting too.

So, what about C vs C++? The question is moot for rinky-dink microcontrollers that don't have a C++ compiler, but for modern "reasonable" architectures (e.g., ARM, MSP430) it's an interesting choice. Most embedded code is straight C, but there's a growing number of C++ folks in the mcu world.

Given a choice, I'll go with C++ in a heartbeat. A major reason is that C++ makes structure initialization much more rational with constructors. C++ objects are implemented in a way that's similar to adding a compiler-managed parameter block to each function, avoiding the need to have so many static variables. Namespaces, templates, virtual functions and references only add to the C++ win.

What say you?
 

Offline jebcom

  • Regular Contributor
  • *
  • Posts: 81
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #1 on: May 21, 2013, 01:40:44 am »
I say it depends on:
1. How valuable object orientation will be to the system.
2. Whether you have resources for the overhead of C++. The executable can be bloated.
For a simple system, I'd go with C, but that's just my opinion. If it gets very involved  you probably want OO.
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2095
Re: Which is better for embedded work: C or C++?
« Reply #2 on: May 21, 2013, 02:11:33 am »
What say you?

I would say please don't lest we get pages of opinion like the assembler thread which verged on trolling.
Pages of opinion are not that interesting because, like arseholes everyone has one.
 

Offline snoopy

  • Frequent Contributor
  • **
  • Posts: 767
  • Country: au
    • Analog Precision
Re: Which is better for embedded work: C or C++?
« Reply #3 on: May 21, 2013, 02:23:56 am »
I use C++ and Visual DSP for an analog devices Sharc DSP. Could never go back to using C after using C++. Much more structured programming and reusable objects etc. Also the Standard Template library comes in handy even with embedded apps ;)

As for bloat-wear I don't think you will write better assembler code than an optimizing C/C++ compiler can especially for a DSP ;)

regards
david
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #4 on: May 21, 2013, 01:17:55 pm »
IMHO it is a good idea. The biggest problem I see with C is that it is easy to overlook a pointer or create a buffer overflow. When used well C++ can avoid these pitfalls. OTOH it doesn't hurt to look at other languages. I plan to experiment a bit with embedded Lua. Maybe even create a relatively cheap box with some I/O with which people can experiment or use it as a controller.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline andete

  • Contributor
  • Posts: 19
  • Country: be
  • famous for its killer edible poets
Re: Which is better for embedded work: C or C++?
« Reply #5 on: May 21, 2013, 01:24:24 pm »
For small micro-controllers I use C++ but I only use namespaces and references and very rarely some templates. No classes or fancy object-oriented stuff. (I'm a functional programming style person)

Just using namespaces allows organizing code more which improves readability and avoids ridiculously long function and variable names.

Using references allows for more defensive coding making clear at compile time that null-pointers are not allowed for a certain code path.
 

Offline andyturkTopic starter

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #6 on: May 21, 2013, 02:52:06 pm »
Pages of opinion are not that interesting because, like arseholes everyone has one.
Some of the stuff in those other threads was pretty good. And besides, any engineer worth his salt should have enough opinion for two arseholes.  :rant:
 

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2184
  • Country: au
Re: Which is better for embedded work: C or C++?
« Reply #7 on: May 21, 2013, 04:15:24 pm »
... And besides, any engineer worth his salt should have enough opinion for two arseholes.  :rant:
:-DD
Any engineer worth his salt shouldn't need fifty thousand lines of compiler generated code to prevent him from using a null pointer!
We should all graduate to EE++ to stop us from reversing polarities in our circuits :)
 

Offline mgronber

  • Contributor
  • Posts: 11
Re: Which is better for embedded work: C or C++?
« Reply #8 on: May 21, 2013, 04:24:30 pm »
2. Whether you have resources for the overhead of C++.

What overhead? With C++ you pay only for the features that you use and you get many nice features for free. The features that you have to pay for are not free in C either if you need such functionality.

It is a no-brainer. I choose C++.
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #9 on: May 21, 2013, 04:45:59 pm »
What overhead? With C++ you pay only for the features that you use and you get many nice features for free. The features that you have to pay for are not free in C either if you need such functionality.

It is a no-brainer. I choose C++.

You can  turn off most features in most C++ compilers, but often that takes effort. e.g. you may need to add a few command line options like:
-fno-rtti -fno-exceptions -fno-threadsafe-statics ...

The 'problem' with C++ is that it is VERY easy to use a feature that has tremendous implications for things like code size. e.g. templates, virtual functions...

Basically you need to know C++ very well in order to know how to understand the relationship between the code that is written and the code that is generated. That way you can know how to fix problems by not using certain features. e.g. Tweaking a class to make it POD (Plain Old Data) ...

In large part this debate depends on your definition of 'embedded'. For some people embedded is an ARM running into the hundreds of MHz with 10s to 100s of MBs of RAM. In those cases the 'bloat' of C++ might be well worth the ability to use 3rd party C++ libraries and the features of C++ that make it work better on large applications.

But, in a more constrained definition of embedded 10s of MHz to a few MB of RAM, the benefits of C++ become a bit more dubious. Get down to microcontrollers, and the debate becomes about C vs Assembly instead of C vs C++.

That all being said, personally, if I have a choice, I use C for things that need the speed (or need to touch hardware), and Python for everything else.
 

Offline mgronber

  • Contributor
  • Posts: 11
Re: Which is better for embedded work: C or C++?
« Reply #10 on: May 21, 2013, 05:39:20 pm »
The 'problem' with C++ is that it is VERY easy to use a feature that has tremendous implications for things like code size. e.g. templates, virtual functions...

We were talking about engineers worth their salt. Right? :)

Quote
Basically you need to know C++ very well in order to know how to understand the relationship between the code that is written and the code that is generated.

Or at least you need to be observant how the code size changes between builds so that accidental bloat can be detected as soon as possible. This applies to plain C too.

Quote
Get down to microcontrollers, and the debate becomes about C vs Assembly instead of C vs C++.

I agree. However, I don't see much reason to use C instead of C++ presuming that there is a proper C++ compiler available. The real question is which features of C++ should be used and which should be avoided.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #11 on: May 21, 2013, 06:28:27 pm »
I agree. However, I don't see much reason to use C instead of C++ presuming that there is a proper C++ compiler available. The real question is which features of C++ should be used and which should be avoided.
The answer to that question is: the features which make the end result too expensive. For low volume products the development costs are the most significant so using a $20 controller instead of a $1 controller may be perfectly justifiable.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #12 on: May 21, 2013, 07:42:41 pm »
I agree. However, I don't see much reason to use C instead of C++ presuming that there is a proper C++ compiler available. The real question is which features of C++ should be used and which should be avoided.

What I was (indirectly) getting at in my previous post was that by using C you don't need to spend time evaluating the impact of each feature ... and which features are used by 3rd party tools/libraries... This can actually be a benefit in the scenario where schedule is one of your biggest constraints. Then again, when schedule is your biggest constraint, using whatever the dev team is familiar/comfortable with is probably best ... even if its a mixture of BrainFsck and Erlang :)
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3713
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #13 on: May 21, 2013, 10:55:31 pm »
C++.  In C++ you don't pay for features you don't use (and it is easy to avoid them!).  At a minimum, you can use C++ as "super-C" with better namespace control (by using non-virtual member functions or namespaces), usable const, overloaded methods, and default arguments.  All of those features are essentially free, they make your code easier to develop, easier to read, and less buggy.  That leaves you the option of using additional features if you need them.  In particular, simple inheritance with virtual methods does add some overhead, no more (and often less) than if you implemented the same in C with explicit dispatch tables.

Templates, exceptions, and RTTI are features more likely to cause unacceptable overhead, but you can always just not use them, or you can use them carefully.

The argument that you might accidentally do something that causes your executable to double in size is not really credible.  Sure it might happen, but that is usually because you were saving a lot of time compared to doing something the hard way in C.  If you have to go back and fix it, you are usually not going to be much worse than if you had done things the hard way the first time.

Also, it is certainly possible to accidentally create bloat in C programs.  Allocating large arrays on the stack, Passing/returning structures by value, excessive inlining all spring to mind.

C++ traditionally lacked good compilers, especially in the embedded world.  In particular, there used to be a lot of embedded C++ compilers didn't achieve the promise of "no overhead for features you don't use", especially with exceptions.  If the C++ compiler for your platform sucks, that is a great reason to stick with C.  Otherwise, C++ really has no downsides. 
 

Offline andyturkTopic starter

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #14 on: May 22, 2013, 03:46:45 am »
The 'problem' with C++ is that it is VERY easy to use a feature that has tremendous implications for things like code size. e.g. templates, virtual functions...
Virtual functions don't cost very much... a little bit of code space for the vtables and a RAM pointer per instance for the vptr.  The thing is, if you need something like virtual functions, there's really no more efficient way to do it.

Templates, on the other hand, can get expensive quickly if you put a lot of method implementations in the template. If you move most of your methods into a base class, then it's not too bad.

Quote
[...] in a more constrained definition of embedded 10s of MHz to a few MB of RAM, the benefits of C++ become a bit more dubious. Get down to microcontrollers, and the debate becomes about C vs Assembly instead of C vs C++.
I'm using C++ (templates, virtual functions, and even multiple inheritance!) on a project with 128K of code space and 10K of RAM. Seems to be working out so far.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13742
  • Country: gb
    • Mike's Electric Stuff
Re: Which is better for embedded work: C or C++?
« Reply #15 on: May 22, 2013, 08:53:01 am »
The answer to that question is: the features which make the end result too expensive. For low volume products the development costs are the most significant so using a $20 controller instead of a $1 controller may be perfectly justifiable.
True, but larger code size will generally also mean higher power consumption, which may be an issue in low-power systems.

I don't know a great deal about C++, but you really want to avoid anything that uses dynamic memory allocation (or more strictly speaking de-allocation)  in an embedded system, as it's very hard to test to verify that it will never run out or become too fragmented to work at some point.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #16 on: May 22, 2013, 11:10:17 am »
I have used dynamically linked lists as dynamic memory before. It works like a charm but you have to allocate / deallocate carefully. C++ can solve those problems.

My software usually is organised as several processes with very little global variables. If there is need for memory then the stack is the source of it. When a process starts the stack is as good as empty and when its exits it leaves the stack empty. If you apply the same mechanism with C++ then memory never gets full or fragmented. Things get interesting when you need buffers to be available for a longer period. In that case you'll need to make sure only a limited number of buffers can exist and that they are always cleaned up at some point. With carefull planning you can prevent memory from fragmenting and C++ makes that easier.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13742
  • Country: gb
    • Mike's Electric Stuff
Re: Which is better for embedded work: C or C++?
« Reply #17 on: May 22, 2013, 12:09:51 pm »
Things get interesting when you need buffers to be available for a longer period. In that case you'll need to make sure only a limited number of buffers can exist and that they are always cleaned up at some point.
..or never cleaned up - i.e. you allocate everything that will ever need allocating, assuming you have room to do that.
The main issue is not so much the actual usage, but testing/convincing yourself that it will never run out in service.
 
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline HackedFridgeMagnet

  • Super Contributor
  • ***
  • Posts: 2028
  • Country: au
Re: Which is better for embedded work: C or C++?
« Reply #18 on: May 22, 2013, 12:47:26 pm »
Quote
The main issue is not so much the actual usage, but testing/convincing yourself that it will never run out in service.
I realise that it depends on your application but for every app i've ever been involved with it is not that hard.
Assuming your watchdog is working, 99% certainty that the uptime is months has been good enough.
To get to something like this reliability on memory deallocation is fairly easy.
I can't remember ever having a serious memory leak problem. [edit. except once in objective c where I really didn't understand the system at all ]
Look at your code, test your code, use templates if you can, pass references, but watch sharing data between threads etc.
« Last Edit: May 22, 2013, 12:49:24 pm by HackedFridgeMagnet »
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #19 on: May 22, 2013, 12:50:11 pm »
There are two simple solutions: checking the space left of the heap is not diffcult because an allocation will fail when the system runs out of memory (which may cause a... whatever is suitable). Checking the stack is also possible. I usually do this by sampling the stack pointer in the timer interrupt. Then I test the stack pointer against the end of the data memory. If the stack pointer is in the data area things went wrong. I also have a command which shows me the lowest stack pointer which (after running for a while) shows the maximum stack usage.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #20 on: May 22, 2013, 02:51:18 pm »
..or never cleaned up - i.e. you allocate everything that will ever need allocating, assuming you have room to do that.
The main issue is not so much the actual usage, but testing/convincing yourself that it will never run out in service.
Whenever possible I like to design a system to start out in the worst case scenario. It makes testing much easier.  e.g. What if your input queue fills up at the same time that your output queue fills up at the same time that EVERY interrupt pin triggers. Having fixed size preallocated queues makes this test case possible, if those queues grow indefinitely, when do you give up testing? 10 entries, 100 entries, 1000000000000000000 entries?

I have used dynamically linked lists as dynamic memory before. It works like a charm but you have to allocate / deallocate carefully. C++ can solve those problems.
The key point for a constrained embedded system is that allocating dynamic memory and then later deallocating it DOES NOT return the system to the same state. You may have just introduced fragmentation in the heap that is effectively irreversible. Allocate and deallocate 10, 100, 1000... times and the system may be effectively useless.

And if you don't look at the big picture and 'gracefully' handle the error condition, you can make things worse. Oh that allocation didn't work ... shucks (instead of rebooting).

Or possibly even worse, even if you can still allocate and deallocate, it gets harder and harder for the memory manager to find free space, and the system gets slower.

C++ makes it easier to never forget to allocate/deallocate, but it also makes it easier to introduce a memory allocation where you weren't expecting it. Did you declare a variable of type Foo in a function in your hard real-time path? Oh, does Foo contain Bar, which contains SuperSmartPointerBufferArray ... and after running for 10 weeks it takes 10ms to allocate instead of 10us.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #21 on: May 22, 2013, 03:32:41 pm »
I have used dynamically linked lists as dynamic memory before. It works like a charm but you have to allocate / deallocate carefully. C++ can solve those problems.
The key point for a constrained embedded system is that allocating dynamic memory and then later deallocating it DOES NOT return the system to the same state. You may have just introduced fragmentation in the heap that is effectively irreversible. Allocate and deallocate 10, 100, 1000... times and the system may be effectively useless.
You have to be really bad at programming if you let that happen. Even on a PC such software is not acceptable. Besides buffers consisting of dynamic linked lists can never become fragmented.
« Last Edit: May 22, 2013, 03:42:48 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #22 on: May 22, 2013, 04:00:06 pm »
You have to be really bad at programming if you let that happen. Even on a PC such software is not acceptable.

It does happen, but on a PC with GBs of RAM and a many layers of memory management (virtual memory, the C library, per process address spaces ...) it is hard to create detrimental fragmentation.

On a memory constrained embedded system with a single flat (small) address space and a slimmed down C library you need much more care to avoid detrimental fragmentation.

I ran into a case recently where we integrated two modules that had each been used/reviewed/tested (just not together).

Module A responded to a request by allocating some memory, doing some processing, and sending back a result several seconds later, at which time it deallocated the memory.

Module B responded to a request by allocating some memory and continuously monitoring something until it got a later request to stop, at which time it deallocated the memory.

During long term testing it was found that if you sent enough requests to A and B the system eventually got unhappy (due to fragmentation). Just using A was fine. Just using B was fine.

Our solution was to declare an upper limit on the number of things B could monitor and preallocate all those buffers ... sure there are other ways to skin that cat, but we needed a quick solution since we were schedule constrained.
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: Which is better for embedded work: C or C++?
« Reply #23 on: May 22, 2013, 06:12:16 pm »
Besides buffers consisting of dynamic linked lists can never become fragmented.

WTF?!?

Could you explain your assertion a little better? Maybe we don't have the same definition of "dynamic linked list."

AFAICT your assertion only makes sense if you only ever have one buffer size in the system. Look at my previous post, imagine module A adds a 2K buffer to its linked list, and module B adds a 4K buffer to its list. And keep in mind there are probably also modules C through Z which occasionally allocate some little tid-bit. Run it long enough and you could have a bunch of 4K buffers with 2K of fragmentation in between each.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Which is better for embedded work: C or C++?
« Reply #24 on: May 22, 2013, 08:18:22 pm »
Imagine you chop the memory in blocks of (say) 128 bytes. Each block of memory also has a size and a pointer which can point to a next block. If you need to store 100 bytes of memory you request 100 bytes from the allocator. The allocator looks for an empty block and returns a handle to that block. Next you call a function which puts the data into the block which updates its size to 100 bytes. If you want to store an additional 50 bytes you request the allocator to extend the buffer by 50 bytes. The allocator knows only 128 bytes fit in one block so it allocates a second block and updates the linkage pointer in the first block. The function which adds data to a buffer can now store 28 bytes in the first block and 22 bytes in the second block.

This all looks complicated but in code it can be implemented quite efficiently. Because buffers are stored as linked lists the order can be completely random. Ofcourse you need functions to put/get/append data to the buffers because you can't have pointers directly to the memory. This is a bit clunky. With C++ you could overload the [] operator and offer indexed acces to a linked-list buffer.

At some point I extended this scheme to a hybrid which also supports malloc/free. In case of malloc/realloc/free a consequtive string of empty blocks is required. However, if most of the software is using the linked blocks scheme it is possible to unfragment it and in case of a re-alloc it is allowed to return a different pointer.

I used this mostly for handling network connections which are not entirely deterministic.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf