News for hackers. Stuff that matters.
Re:Size cost of C++ exception handling on embedded platforms by userbinator on Monday May 16, 2016 @04:45AM (#11705039)
I think this shows clearly that compilers are still quite bad at "optimising in the small", since they tend to all be based on the "link in everything and let later passes strip out some of it" principle, whereas what's really needed is for them to link in code only if it can be proved it will be needed/can't be proved to be unneeded. And even after his efforts at removing unused code, there's still plenty remaining (more than order of magnitude difference.) Ideally the compiler should be able to optimise the exception code to become identical to the no-exceptions code, something that a human could easily do in this case but the compiler couldn't.
Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @04:56AM (#11705086)
Link Time Optimisation is what you're referring to (-flto) and that wont solve the issue. exception handling is inherently unsuited for embedded systems.

The size & performance overhead is one thing, but the model of attempting to "handle" errors is incorrect. In most cases, a PANIC situation should lead to a watchdog reset.

Exceptions should be for exceptional cases, not the usual program logic. In embedded systems, exceptional cases == reset.

Re:Size cost of C++ exception handling on embedded platforms by tremon on Monday May 16, 2016 @06:30AM (#11705408)
Exceptions should be for exceptional cases

Why? Simply because the words look alike?

I think you're painting a false dichotomy here. There's a whole world of program state between "usual program logic" and "exceptional cases".

Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @06:56AM (#11705492)
defined recovery cases are not exceptions.

exceptions are breaks from what you had assumed to be constant.

There is a reason program logic is not placed into exception handlers... the readability would be completely destroyed.

Re:Size cost of C++ exception handling on embedded platforms by barrkel on Monday May 16, 2016 @08:01AM (#11705738)
You're thinking of asserts, not exceptions.

Exception usage can usually be split into three buckets: (1) programming errors where abort() or equivalent isn't suitable (e.g. libraries); (2) semantic errors at the application level where language provided unwinding is used as a convenience to jump back to the core event / request loop and provide an error to the user or client; and (3) to provide out-of-band error information for failures when interacting with non-deterministic systems (e.g. failure to open a file or communicate with a device, where the natural function to write returns a value, rather than a success or error code).

There are alternative solutions to all three, and all three may not apply to every environment. For embedded systems, case (1) may indeed not apply. But cases (2) and (3) may be useful as a programming convenience to automate the idiom of checking error conditions and aborting the current operation. If checking error conditions and aborting is fully automated (like monadic Result handlers in e.g. Rust) then you start approaching an isomorphic semantics to exceptions, with no necessary difference in implementation details.

Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @08:27AM (#11705814)
nope, definitely not thinking of asserts, they are nothing to do with this situation.

program logic encoded in an exception handler is undeniably less easy to read than explicitly coded error cases.

Also, the non-locality of the decision making means the further away from the error-site you are, the more context you have to keep in your head.

This similar to what deep inheritance hierarchies suffer from, non-local logic. you end up jumping all around your source tree trying to figure out the full context that an error has occurred in.

Re:Size cost of C++ exception handling on embedded platforms by barrkel on Monday May 16, 2016 @09:10AM (#11705996)
"program logic encoded in an exception handler is undeniably less easy to read than explicitly coded error cases"

For which category of exceptions? For interaction with non-deterministic systems where you can make a localized decision - and this is fairly rare - I'd agree with you. For all the other categories, I think you're wrong. If you never used exceptions in the other ways, this will of course colour your thinking.

Re:Size cost of C++ exception handling on embedded platforms by kbenson on Monday May 16, 2016 @01:50PM (#11708100)
That's a very strong statement. You really believe there can't possibly exist any instance where program logic in an exception handler ends up being easier to read? That assumes you know enough about every possible permutation of logic flow to know that exceptions could not benefit it.
Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @03:31PM (#11708946)
Of course not, I'm talking about a general rule.

No rules are universal.

Re:Size cost of C++ exception handling on embedded platforms by kbenson on Monday May 16, 2016 @05:24PM (#11709754)
Sure. The real point I'm getting at is that overly strong statements lead to arguments, where people take your statement at face value. Hyperbole is rarely useful in a serious discussion. It just means people have to work to determine your real stance because it may not match exactly what you said.

You could have said "I've never seen a case where exception handling resulted in more clear and easier to read code, and I doubt I'll ever encounter such a situation" and I think that would convey your opinion clearer (assuming I understand it correctly).

> No rules are universal.

We're talking about CS and programming here, where there are plenty of cases where things have been formally proven. Some rules are universal. No reason to use absolutist statements where they don't apple.

Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @06:55AM (#11705490)
(replying to both)

protocol stack logic is just that... logic, no need to short circuit returns with the use of exceptions.

Exceptional case are things that you have a-priori determined to be constant, i.e. the existence of a FLASH device, an RTC working correctly for example. If any of those devices fail, it could be considered an exceptional case, therefore the only action left to you is to reset and hope the condition clears. boot-loops obviously have to be handled also.

There is a world of difference between defined recovery cases and just throwing an exception because you dont know how to "handle" it.

Re:Size cost of C++ exception handling on embedded platforms by mattkrause on Monday May 16, 2016 @01:58PM (#11708167)
"You" this particular function might not know how to handle it, but it's possible that some other part of the program does.

To run with your example, I could imagine handling a missing storage device in lots of different ways, including a) Retry the operation b) Alert the user and block until a device (re)appears c) Switch to an alternative storage location d) Replace the to-be-read-in values with some sensible defaults.

It seems to me that it would be easier to write this logic once and place it in an exception handler than it would be to wrap every I/O operation in a thicket of if/else clauses.

Re:Size cost of C++ exception handling on embedded platforms by adrianratnapala on Monday May 16, 2016 @05:57AM (#11705307)
Depends on the what the embedded system is doing. Right now I am working on a system with a real-time cycle handler and a non-real time thread that handles RPCs. For the real-time part, what you say is more-or less right.

But in the RPC thread is a lot more like non-embedded code: if I detect an error deep in the stack, I can just throw an exception and catch at the top level. The PC gets an error message and the embedded system treats it as a no-op.

Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @06:57AM (#11705496)
defined recovery cases are not exceptions. thats program logic.

Placing program logic into exception handlers is obfuscation.

Re:Size cost of C++ exception handling on embedded platforms by adrianratnapala on Monday May 16, 2016 @07:20AM (#11705575)
Can you unpack this for me? Are you talking about the RPC error handling I described?

As best I understand your argument, it is circular. You assert that if it is an exception, then the only thing to do is reset. When I give a counter-example, you define it as "not an exception" -- presumably because a reset is not desirable.

I agree that defined recovery cases are part of the program logic. But what reason -- beyond a slogan, do you have for reject exceptions as a tool for implmenting that part of the logic? How is it "obfuscation" to do the catch-and-report in the RPC front-end?

The danger I know of with exceptions is that throw sites are invisible, which makes it easy to neglect clean-up actions on error paths. Is that what you meant?

Re:Size cost of C++ exception handling on embedded platforms by TickleSteve on Monday May 16, 2016 @07:57AM (#11705718)
all I'm saying is that if you have a defined recovery process, put it in normal logic, not exception handlers.

If you don't have a defined recovery process, that technically would be an exceptional case... but because of the nature of embedded systems, a reset is the only reasonable recovery mechanism (a catch all).

Therefore, there is no place for exception handling in embedded systems (as a general rule. Of course there are exceptions... ;o)

The dislike of exception handlers is also that they harm readability, The further you get away from a call-site the more context you have to hold in your head making it more complex.

Keeping error recovery local to the logic improves everything, from readability to code size to complexity and performance.