Hacker News new | ask | show | jobs
by kllrnohj 147 days ago
If you forget to handle a C++ exception you get a clean crash. If you forget to handle a C error return you get undefined behavior and probably an exploit.

Exceptions are more robust, not less.

3 comments

Yeap. forgetting to propagate or handle an error provided in a return value is very very easy. If you fail to handle an exception, you halt.
For what it's worth, C++17 added [[nodiscard]] to address this issue.
You should compare exceptions to Result-style tagged unions in a language with exhaustiveness checks, like Rust. Not to return codes in C, lmao.

Everyone (except Go devs) knows that those are the worst. Exceptions are better, but still less reliable than Result.

https://home.expurple.me/posts/rust-solves-the-issues-with-e...

Rust is better here (by a lot), but you can still ignore the return value. It's just a warning to do so, and warnings are easily ignored / disabled. It also litters your code with branches, so not ideal for either I-cache or performance.

The ultimate ideal for rare errors is almost certainly some form of exception system, but I don't think any language has quite perfected it.

> you can still ignore the return value

Only when you don't need the Ok value from the Result (in other words, only when you have Result<(), E>). You can't get any other Ok(T) out of thin air in the Err case. You must handle (exclude) the Err case in order to unwrap the T and proceed with it.

> It also litters your code with branches, so not ideal for either I-cache or performance.

That's simply an implementation/ABI issue. See https://github.com/iex-rs/iex/

Language semantics-wise, Result and `?` are superior to automatically propagated exceptions.

> like Rust

Where people use things like anyhow.[0]

[0] https://docs.rs/anyhow/latest/anyhow/

Anyhow erases the type of the error, but still indicates the possibility of some error and forces you to handle it. Functionality-wise, it's very similar to `throws Exception` in Java. Read my post
As a matter of fact I did when it appeared on hn.

>forces you to handle it.

By writing `?`) And we get poor man's exceptions.

Poor man's checked exceptions. That's important. From the `?` you always see which functions can fail and cause an early return. You can confidently refactor and use local reasoning based on the function signature. The compiler catches your mistakes when you call a fallible function from a supposedly infallible function, and so on. Unchecked exceptions don't give you any of that. Java's checked exceptions get close and you can use `throws Exception` very similarly to `anyhow::Result`. But Java doesn't allow you to be generic over checked exceptions (as discussed in the post). This is a big hurdle that makes Result superior.
>Poor man's checked exceptions.

No, it's not quite the same. Checked exceptions force you to deal with them one way or another. When you use `?` and `anyhow` you just mark a call of fallible function as such (which is a plus, but the it's the only plus), and don't think even for a second about handling it.

> If you forget to handle a C++ exception you get a clean crash

So clean that there's no stack trace information to go with it, making the exception postmortem damn near useless.