Embedded C++ : to use exceptions or not?
I realize this may be subjective, so will ask a concrete question, but first, background:
I have always been an embedded so开发者_JS百科ftware engineer, but usually at Layer 3 or 2 of the OSI stack. I am not really a hardware guy. I have generally always done telecoms products, usually hand/cell-phones, which generally means something like an ARM 7 processor.
Now I find myself in a more generic embedded world, in a small start-up, where I might move to "not so powerful" processors (there's the subjective bit) - I cannot predict which.
I have read quite a bit about debate about exception handling in C++ in embedded systems and there is no clear cut answer. There are some small worries about portability and a few about run-time, but it mostly seems to come down to code size (or am i reading the wrong debates?).
Now I have to make the decision whether to use or forego exception handling - for the whole company, for ever (it's going into some very core s/w).
That may sound like "how long is a piece of string", but someone might reply "if your piece of string is an 8051, then don't. If, OTOH, it is ...".
Which way do I jump? Super-safe & lose a good feature, or exceptional code and maybe run into problems later?
In terms of performance, my understanding is that exceptions actually reduce the size and increase the performance of the normal execution paths of code, but make the exceptional/error paths more expensive. (often a lot more expensive).
So if your only concern is performance, I would say don't worry about later. If today's CPU can handle it, then tomorrows will as well.
However. In my opinion, exceptions are one of those features that require programmers to be smarter all of the time than programmers can be reasonably be expected to be. So I say - if you can stay away from exception based code. Stay away.
Have a look at Raymond Chen's Cleaner, more elegant, and harder to recognize. He says it better than I could.
The choice of whether to use exceptions or not should really lie with whether they are going to fit your program's problem domain well or not.
I've used C++ exceptions extensively, both in retrofitting into old C code, and in some newer code. (HINT: Don't try to re-fit 20 year old C code that was written in a low memory environment with all manner of inconsistent exceptions. It's just a nightmare).
If your problem is one that lends itself to handling all the errors in one spot (say, a TCP/IP server of some sort, where every error condition is met with 'break down the connection and try again'), then exceptions are good - you can just throw an exception anywhere and you know where and how it will be handled.
If, on the other hand, your problem doesn't lend itself to central error handling, then exceptions are a ROYAL pain, because trying to figure out where something is (or should be) handled can easily become a Sisyphean task. And it's really hard to see the problem just by looking at the code. You instead have to look at the call trees for a given function and see where that function's exceptions are going to end up, in order to figure out if you have a problem.
The most problem with exceptions -- they don't have predictable time of execution. Thus they are not suitable for hard real-time applications (and I guess most embedded application doesn't fall in this category).
The second is (possible) increasing of binary's size.
I would propose you reading of Technical Report on C++ Performance which specifically addresses topics that you are interested in: using C++ in embedded (including hard real-time systems) and how exception-handling usually implemented and which overhead it has.
I'd say use exceptions appropriately if the runtime environment supports them. Exceptions to handle extraordinary conditions are fine, and can cause little overhead depending on the implementation. Some environments don't support them, especially in the embedded world. If you ban them, be careful to explain why. I once had a guy that, when told not to use exceptions, did a divide by zero instead. Not exactly what we had in mind.
I think the problem is that many people voice their opinion without having a solid understanding of how exception handling in C++ works.
I have recently started at a new company, and there is consensus that we should not use exceptions, because we can't test them, because nondeterministic behaviour, etc etc. All wrong, of course.
When we talk about the overhead of having exception handling used in the code, we need to carefully consider overhead on top of what? Granted it comes at a cost, but that is the cost of alternative? Say we are using return error codes. In such scenario HALF of the if() statements in the source code will be dedicated to testing error codes and forwarding them up the call stack. Not making this up, actual metric of the codebase I'm looking at. And most of it is to deal with a) events that can't pretty much ever happen, like not having memory at the start of an embedded application and b) events that if they actually happen, we can not do anything about anyway, other than shutdown.
In this case introduction of exception handling would significantly reduce complexity of the code, separating handling of rare events from the business as usual logic. And saves ton's of overhead, because the error code checking is happening all the time. Further, it significantly reduces the size of the code. Think how much effort is needed to propagate error codes up the stack through 10 different functions, until we get somewhere where we can officially bail. Using the exception handling you can bypass the 10 intermediary levels of functions, and go straight to where we can deal with it.
精彩评论