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

Exceptions are a really valuable programming tool , but you can live without them. The cost of not having exceptions is usually giving every function in your code the option to return an error value.

It takes some time getting used to, but it also creates the habbit of checking error codes on every function you call. It also makes handling errors something you do as soon as possible (and in the most recoverable way).




True, and a good type system will enforce that you check for errors. However, depending on how often errors occur in your program, this can actually make your code slower. Good exception handling implementations are "zero-cost", meaning that there is no performance impact in the happy path (when no exceptions are raised). C-style error handling (an if statement) is actually slower, at least in non-embedded environments.


In C, there are ways you can get the optimizer to turn if-based error handling into something that only spends one or two instructions; using __builtin_expect[0] can decrease the cost of a condition by letting the branch predictor pick the "right" thing to expect. That way you end up only paying the price of the branch (and maybe the jump) instructions without any pipeline flushes or stalls.

[0]: http://blog.man7.org/2012/10/how-much-do-builtinexpect-likel...


I wonder how much slower. Are there any measurements out there? Of a CPU correctly predicting the branches of all "happy path" error code checks and seeing how much overhead that is?


I'm going to go as far as saying that having to manually add error checking and propagation code to every function in your program is so bad (in several ways) as to be flat-out unacceptable. In my experience, the main kind of situation where it's okay to do without exceptions is when you can handle an error by printing an error message and promptly exiting the program. (Of course, this can be regarded as throwing a coarse-grained exception for which the operating system provides the handler and cleanup.)


Exceptions have the same problem as return codes in that you need to be careful to leave things in a consistent state if a function throws an error. RAII can help to some extent in both cases, but doesn't magically enforce that your classes and data structures are internally consistent.

My experience has been that error paths have a way of getting things into inconsistent states, and then you're in trouble regardless.

Checking return codes is annoying but if you're wanting to write robust software, your code needs to be in some way aware of every possible error path.


You can indeed live without them. In C++, the trade-off is that you are now responsible for manually writing and maintaining any and all error propagation code, including remembering to check every relevant return value.


Plus you're pretty much screwed on RAII since you cannot return a value from the initializer. So by not using exceptions in C++, you also will often end up requiring a separate init function that can return errors.


> ...including remembering to check every relevant return value.

To be fair, there are compiler flags to check this. And if not, there are static analysis tools that do the same.


I was slightly amazed I had never heard of such a thing, but sure enough, it does exist: It's -Wunused-result on gcc (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html). You still need to manually add the warn_unused_result attribute to each function though.

There's also the [[nodiscard]] attribute of c++17.


Yup, that's how Rust does it and I vastly prefer it to C++(or Java) exceptions. The compiler forces you to handle the value so you still have all the enforcement of checked exceptions.

Option/Result are really well designed and let you express all sorts of wonderful flow. Being able to .and_then(), .or_else() or the combination of them and many others is just sublime. The doc page goes into quite a bit of detail: https://doc.rust-lang.org/book/error-handling.html




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

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

Search: