3 ms·
I get being against exceptions in a language like C++ where it can leave your program in a really weird state and have some ugly performance implications, but I
by overgard 12y ago
I get being against exceptions in a language like C++ where it can leave your program in a really weird state and have some ugly performance implications, but I don't get the argument in languages where it can work just fine.
The argument seems to be "you should be checking for errors anyway", but I feel like there are basically two types of errors: the obvious kind that you're going to check for anyway (or get bug reports), like network disconnects and bad files, and the "how the hell did that even happen" exception. For the obvious exceptions it seems like a wash, other than the try catch block being a bit cleaner, but for the "hell the hell did that happen" error exceptions seem way more useful. I'd much rather my program explode immediately than risk someone letting the error passing silently because people didn't check err because like "that will never happen". I know, functions can call panic and all that, but it just seems clumsy for no net gain.
I do think there's one type of error checking that doesn't get enough love (I don't know if Go has this, but I'm guessing probably?). "assert" that gets removed in release builds. It's kind of silly when you're working alone, but in a team of programmers or for libraries it's awesome, because it's basically like runtime documentation that gets compiled out. So you can warn your fellow devs about things without it bloating your program. The newer C++ has a really great feature called "static_assert", which is basically a compile time assertion, which can be handy for things like checking in various places that maybe if the count in enum changed, that you accounted for it in another spot of the code, or that certain aspects of a new platform sit right, or things like that.
- deathanatos 12y ago> I get being against exceptions in a language like C++ where it can leave your program in a really weird state If you're programming in modern C++, then exceptions allow you cleanly (as in, clean code) leave your program in a very well defined state. You have to adhere to RAII, and there's a lot of C++ shops out there that don't allow RAII (and are wary of exceptions, because they ignore RAII). I've routinely used exceptions in C++ as a both efficient and clean way to propagate errors out to a stack frame that can handle them, fully confident that RAII will clean up as I go. > and have some ugly performance implications More than having an error object that the calling frame needs to check? If I understand Go (and, since it's mentioned here and I think is relevant, Rust's) setup, each stack frame between the frame that can handle the error and the one where the error occurred must check that an error did indeed occur, and if so return it. Rust makes this pretty through macros, and the article has some good thoughts on it for Go. Nonetheless, can the compiler compile that to better than an `if error { return error }` type check? My understand of C++ exceptions is that this was basically how things _were_ done (but no longer). Previously, exceptions were managed by "sjlj" (short for setjmp, longjmp, the calls used to manage exceptions); any frame that _could_ have an exception would need to call setjmp on entry, and this was a bit hefty. However, my understanding is that, at least for g++ on Linux, C++ has abandoned this in favor of a newer scheme called "dwarf2"[1]; this scheme is such that entering a "try" (or a stack frame where RAII would need to do actual cleanup) is free (rather, it is covered as part of the normal stack setup, really), leaving it gracefully is also free; only during actual stack unwinding do exceptions add code/performance penalties. I think there is an unfortunate amount of information that C++ exceptions are inefficient left over from the sjlj days. [1] http://www.x86-64.org/documentation/abi.pdf http://www.x86-64.org/documentation/abi.pdf
- Rusky 12y agoEntering a try with newer implementations of exceptions is free in that it doesn't execute anything extra, but it's not free. It inhibits the optimizer and creates a lot of duplicated code in the binary, as well as forcing exception safety on the programmer, which is pretty hard to achieve completely, efficiently, and/or cleanly.
- overgard 12y agoYeah, I mean, that can work, but I feel like the phrase "in modern C++" always has the hidden caveat of "Unless you're stuck with a bunch of legacy junk". A lot of times you end up having to use legacy code you can't trust. Your stuff is RAII, but this old legacy code you have to link with... and nobody wants to rewrite it... you probably get the point. I'm not against C++ exceptions, I just think there are legit reasons for shops to avoid it in that particular language . But I like exceptions in general.
- xamuel 12y ago>I'd much rather my program explode immediately than risk someone letting the error passing silently because people didn't check err because like "that will never happen". Note that with java's checked exceptions, we get the exact opposite effect: lazy programmers catching every exception and either doing nothing at all with it or at best, printing the stacktrace and moving on. And it doesn't matter if you're not lazy yourself, the third-party code you reuse will do it. Then there are exceptions that shouldn't even be checked, for example, you call UrlDecode and specify "UTF-8", gotta catch an exception in case "UTF-8" isn't a valid encoding name! >try catch block being a bit cleaner Except when you want to declare a variable and initiate it in the same line, but can't because then it would be scoped to the try block