If you use C++ without exceptions, it means you cannot use the STL or any library that throws. Pretty weak.<p>Additionally, almost all examples of "exceptions are bad", fall short because of RAII (at least in C++) or finally clauses (in other languages).<p>Good reasons for (almost) not using exceptions (in C++):<p>- Performances<p>- "Expectability"/readability<p>- Platform-dependant constraints<p>There are probably others, but the article only talks about the "readability" arguments without even mentioning things such as exceptions specifications.<p>One thing you need to remember about exceptions: they're nothing more than a fancy goto.
Can someone who uses exceptions in large systems offer a comment on <i>which</i> exceptions they throw?<p>One of the problems I have in trying to design with exceptions is that they seem to offer a lot of potential to break abstraction layers.<p>As a concrete example, if you have a cacheing layer which - say - is implemented over the filesystem. In the event of an inability to access the correct location, the low-level routines might throw a permission-related exception. If you swap out the filesystem cacheing implementation with, say, one based on memcached you might instead get a network-related exception.<p>Neither of these types really make sense in the context of a 'cacheing layer error', they seem to leak implementation details - breaking the abstraction.<p>Do people accept this, or do they catch-and-rethrow new exception types at major layer boundaries? (e.g. in the above two implementations, both low-level exceptions may be caught and rethrown as "CacheInitialisationError" with some perhaps some additional diagnostic about the underlying cause). If they have such API-specific error types, do you go to the trouble of modelling an exception type hierarchy? So all your 'cache layer' exceptions inherit from 'CacheError' so a higher level can catch all "CacheExceptions" in one place? This seems like a lot of additional modelling effort, is it commonplace?<p>To my mind, the possible exceptions a API call may make (or equivalently, the errors it could return) are <i>part</i> of the API, and the errors need to be at the same conceptual level as the rest of the API. (So you can't have filesystem errors in a generic cache API).<p>What happens in practice?
Example from the article criticizing exceptions:<p><pre><code> open_the_gate()
wait_for_our_men_to_come_in()
close_the_gate()
</code></pre>
D programming language for example has an excellent support for RAII with ScopeGuard statement <a href="http://dlang.org/statement.html#ScopeGuardStatement" rel="nofollow">http://dlang.org/statement.html#ScopeGuardStatement</a> The example in question will become:<p><pre><code> open_the_gate();
scope(exit)
close_the_gate();
wait_for_our_men_to_come_in()
</code></pre>
Then even if wait_for_our_men_to_come_in() throws we still close the gate. There is additional granularity - we can execute statement on success or failure too.<p>The technique was originally developed by Andrei Alexandrescu for C++ and described in <a href="http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758" rel="nofollow">http://www.drdobbs.com/cpp/generic-change-the-way-you-write-...</a>
No discussion of Exceptions vs Error codes is complete without referring to Joel Spolsky's Exceptions article:<p><a href="http://www.joelonsoftware.com/items/2003/10/13.html" rel="nofollow">http://www.joelonsoftware.com/items/2003/10/13.html</a><p>Also:<p><a href="http://channel9.msdn.com/Blogs/Charles/Erik-Meijer-and-Robert-Griesemer-Go" rel="nofollow">http://channel9.msdn.com/Blogs/Charles/Erik-Meijer-and-Rober...</a><p>Erik Meijer interviews Robert Griesemer about Go. They chat about exceptions for error codes. The exception talk starts ~8:00.<p>Erik is in favor of failing fast with exceptions b/c most of the time, when you have an exception in an application, you want to fail fast because there is "nothing you can do" at the point where you have an unexpected null, etc.<p>Very interesting discussion between two smart guys.
Java world -> Aren't checked exceptions just error codes that use types instead of arbitrary values and compiler gaurantees?<p>And wasn't the thought that checked exceptions would be better for critical code because the compiler guaranteed that they were handled.<p>I'm no fan of java's error handling, but I think that the insinuation that the lack of any formal error handling makes you write less error prone code is bordering on the absurd.<p>Detail oriented individuals write robust code given the constraints of their environment. If its arbitrary strings that indicate error state they use strings if its integer return codes they use integer return codes.
This is why I hate all modern programming languages (I'm actually writing an article on that >.>). The conclusion to this article is the same as many others. Programming language feature X is better in situation A and Programming language feature Y is better in situation B. Where the features are often incompatible (or fulfill similar areas, error handling in this case). The solution is of course to have multiple programming languages in your projects that have both situation A and situation B<p>But languages are so annoying to integrate (where they can call into each other and support each other's features, without ridiculous glue code. Let alone swap code in the middle of a file), unless they were designed to (e.g. python and C). It is hell to set up the library dependencies and get the compilers to cooperate with each other. Which is why most just pick the language that's best for the majority of their project (or spend large amounts of developer time integrating other programming languages (not scripting languages, that's related but not quite the point) into their project).<p>Which is why we need the ability to change semantic languages within the same programming system, and have the programming system resolve the differences between the semantic languages automatically. So you can have one semantic language with features designed for situation A and another with features designed for situation B and just swap between them as needed and have them compile together automatically. This is what my Masters thesis and probably what my PhD dissertation will be on.
Another weak article. He never mentions<p>try {
makeAMess()
errorProneOperation()
} finally {
cleanUp()
}<p>your first instinct should be to use finally, not catch, but Java brought us the tragedy of checked exceptions (in which your #1 motivation in working with exceptions is to shut up the compiler) and the bad habits have been adopted by people who use other languages that copy the (otherwise pretty good) Java exception handling style.
Exceptions are far far more readable than error code handling. Exceptions allow one to separate error handling from the structure of the "mainline" execution path of an algorithm. Weaving if/else statements in and out of the mainline path of an algorithm muddies the intent. Exceptions help with this greatly. Instead of having to comprehend the entirety of the algorithm (when exception handling can sometimes take up 50% or more of the code), you can zero in on the most common execution path. Then understand the degenerate cases in turn. The fewer branches your brain has to process in any given moment is a boon for readability.<p>Yes, exceptions are just fancy goto's--but that is a good thing! Goto's when used sparingly can greatly increase the readability of exception handling code. Exceptions simply create a language level abstraction for this functionality.