4 ms·
In low-level systems software, which is a primary use case for C++, exceptions can introduce nasty edge cases that are difficult to detect and reason about. The
by jandrewrogers 9mo ago
In low-level systems software, which is a primary use case for C++, exceptions can introduce nasty edge cases that are difficult to detect and reason about. The benefits are too small to justify the costs to reliability, robustness, and maintainability.
Exceptions in high-level languages avoid many of these issues by virtue of being much further away from the metal. It is a mis-feature for a systems language. C++ was originally used for a lot of high-level application code where exceptions might make sense that you would never use C++ for today.
- BeetleB 9mo ago> In low-level systems software, which is a primary use case for C++ I can assure you: Most C++ SW is not written for low-level. > exceptions can introduce nasty edge cases that are difficult to detect and reason about. That's true, except for languages that ensure you can't simply forget that something deep down the stack can throw an exception. BTW, I'm not saying C++'s exceptions are in any way good. My point is that exceptions are bad in C++, and not necessarily bad in general.
- beached_whale 9mo agoThe model of communicating errors with exceptions is really nice. The implementation in C++ ABI's is not done as well as it could be and that results in large sad path perf loss.
- jandrewrogers 9mo ago> That's true, except for languages that ensure you can't simply forget that something deep down the stack can throw an exception. Sometimes it is not safe to unwind the stack. The language is not relevant. Not everything that touches your address space is your code or your process. Exception handlers must have logic and infrastructure to detect these unsafe conditions and then rewrite the control flow to avoid the unsafety. This both adds overhead to the non-exceptional happy path and makes the code flow significantly uglier. The underlying cause still exists when you don't use exceptions but the code for reasoning about it is highly localized and usually has no overhead because you already have the necessary context to deal with it cleanly.
- le-mark 9mo ago> Sometimes it is not safe to unwind the stack. This where garbage collected languages shine.
- matheusmoreira 9mo agoExceptions are actually a form of code compression. Past some break even point they are a net benefit, even in embedded codebases. They're "bad" because the C++ implementation is garbage but it turns out it's possible to hack it into a much better shape: https://youtu.be/LorcxyJ9zr4 https://youtu.be/LorcxyJ9zr4
- secondcoming 9mo agoThere is no such thing as the 'C++ implementation' of exceptions. Each vendor can do it differently.
- beached_whale 9mo agoC++ exceptions are fast for happy path and ABI locked for sad path. They could be much faster than they are currently. Khalil Estell did a few talks/bunch of work on the topic and saw great improvements. https://youtu.be/LorcxyJ9zr4 https://youtu.be/LorcxyJ9zr4
- beached_whale 9mo agoOops, I meant they are ABI locked so sad path cannot be fixed.
- kllrnohj 9mo agoIf 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.
- nomel 9mo agoYeap. 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.
- vasilvv 9mo agoFor what it's worth, C++17 added [[nodiscard]] to address this issue.
- Expurple 9mo agoYou 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-exceptions/ https://home.expurple.me/posts/rust-solves-the-issues-with-e...
- drysine 9mo ago> like Rust Where people use things like anyhow.[0] [0] https://docs.rs/anyhow/latest/anyhow/ https://docs.rs/anyhow/latest/anyhow/
- Expurple 9mo agoAnyhow 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
- 9mo ago
- senfiaj 9mo ago> "In low-level systems software, which is a primary use case for C++, exceptions can introduce nasty edge cases that are difficult to detect and reason about. The benefits are too small to justify the costs to reliability, robustness, and maintainability." Interestingly, Microsoft C / C++ compiler does support structured exception handling (SEH). It's used even in NT kernel and drivers. I'm not saying it's the same thing as C++ exceptions, since it's designed primarily for handling hardware faults and is simplified, but still shares some core principles (guarded region, stack unwinding, etc). So a limited version of exception handling can work fine even in a thing like an OS kernel.
- jandrewrogers 9mo agoFWIW, I think it is possible to make exception-like error handling work. A lot of systems code has infrastructure that looks like an exception handling framework if you squint. There are two main limitations. Currently, the compiler has no idea what can be safely unwound. You could likely annotate objects to provide this information. Second, there is currently no way to tell the compiler what to do with an object in the call stack may not be unwound safely. A lot of error handling code in C++ systems code essentially provides this but C++ exceptions can't use any of this information so it is applied manually.
- drnick1 9mo ago> In low-level systems software, which is a primary use case for C++ I don't this this is true. There is A LOT of C++ for GUI applications, video games, all kind of utilities, scientific computing and others. In fact, I find that the transition to "modern" alternatives from native GUI toolkits in C/C++ has led to a regression in UI performance in general. Desktop programs performed better 20 years ago when everything was written in Win32, Qt, GTK and others and people did not rely on bloated Web toolkits for desktop development. Even today you can really feel how much more snappy and robust "old school" programs are relative to Electron and whatnot.
- saghm 9mo agoTo clarify, you think that low-level systems software is only a secondary use case for C++? The part you quoted does not make claims about whether there are other primary use cases, just that low-level systems software is one of them, so it's not clear why it being useful elsewhere is a rebuttal of that.
- TylerE 9mo agoThere are only so many OS kernels to be written. Nothing else is really low-level these days.
- saghm 9mo agoI don't think I agree with that. To me, how low-level something is makes more sense sense as a spectrum rather than a binary, and there are certainly other things that I'd consider to fit into the lower end than just OS kernels. Over the summer I contracted for a company making satellites working on software they had that facilitated interactions between various software and hardware components that had to run a 20 ms loop for processing everything, with delays cascading throughout those other components and causing systemic issues. This was all in userland (the OS stuff was managed by another team), but a tracing garbage collector would have been pretty much a non-starter due to the potential to miss the expected timing of a loop iteration. You could handwave this objection by saying it's not "really" low level or that "nothing" was an exaggeration, but at that point it seems like we'd be back to the original question of why it's wrong to say that this isn't a primary use case for C++.