Hacker News new | past | comments | ask | show | jobs | submit login

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.




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".


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.


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.


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.


"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.


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.


Of course not, I'm talking about a general rule.

No rules are universal.


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.


(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.


"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.


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.


defined recovery cases are not exceptions. thats program logic.

Placing program logic into exception handlers is obfuscation.


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?


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.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: