3 ms·
The trouble comes when you need to clean up resources while bailing out. Exception handlers and RAII are great for this, but when you don't have such features a
by kstenerud 12y ago
The trouble comes when you need to clean up resources while bailing out. Exception handlers and RAII are great for this, but when you don't have such features available, goto is pretty handy:
https://github.com/kstenerud/KSCrash/blob/master/Source/KSCrash/Recording/Sentry/KSCrashSentry_MachException.c#L340 https://github.com/kstenerud/KSCrash/blob/master/Source/KSCr...
If I ever had to add more resources or steps into the mix here, I'd be in a world of hurt pretty quick if I were using a complicated nest of breaks and if-else. One could forcefully encapsulate each step into a separate function, but then you start to trend towards a forest of tiny little trees that you're not even sure what to name anymore, and the overall structure of the function and what it's doing become muddled.
- Animats 12y agoIt's hard to do right. RAII handles initialization fine, but error handling in the destructors is hard. Raising an exception in a destructor seldom ends well. Go's "defer" has the same problem - what do you do if there's an error in a deferred call? Most languages with exceptions have problems in this area. Python's "with" clause seems to be the best solution so far. The "with" clause calls __enter__ at the start and __exit__ at the end. The __exit__ gets called no matter how you leave the "with" clause. This includes exceptions and returns. Importantly, there are parameters to __exit__ which provide information about what's going on when an __exit__ is executed because of an exception. Exceptions in __exit__ can be handled and passed on, even for nested "with" clauses. Writing a proper __exit__ is a bit tricky, but that's typically done only for standard resources such as files, connections, and locks. So nested error handling via exceptions can work well if the scoped open mechanism ("with") and the exception mechanism play well together. It took a decade to get that retrofitted into Python, but in the end, it worked well. Rust's error types are sound, but result in rather bulky code. I've written on this before.