TITLE: the philosophy of exceptions (according to Herb) (Newsgroups: comp.lang.c++.moderated, 16 Apr 97) HOPPS: kjhopps@mmm.com >: How would you distinguish between an error and an exceptional condition? OLEG: Oleg Zabluda >Exceptional condition is an exceptionally rare error :-). The one >you don't expect to ever happen, but must handle just in case. [ Herb is author of "Teach Yourself C++ in 21 Days" (I hope I got the title right) and is a regular in the OOD/C++ news groups. -adc ] SUTTER: herbs@cntc.com (Herb Sutter) (Honest, this was originally going to be a two-line reply...) "All disasters are errors, but few errors are disasters." -- hps, 1997 An error is a failure that can be expected in normal operation (regardless of how rarely), and by corollary one that the function can/should deal with. An exception is of the "what the heck izZAT, I just can't recover" variety. For example, consider the way a certain popular C++ networking library handles failure conditions (I won't name the vendor, and we do like the library overall and use it extensively). When you initiate a TCP/IP connection to another machine, and the remote host is not present or responding, the connection function throws an exception. To me, this is a gross abuse of exceptions and I would never design it this way... that should be an error status return code, since "couldn't connect" is a valid and normal condition (regardless of how rare) and not a violation of a solemn guarantee. Making this an exception is the equivalent of saying "my connect function guarantees that you will connect successfully no matter what, and that the remote machine shouldn't be waiting for the call is utterly unexpected and I just can't deal with it"... which is, of course, unreasonable. On the other hand, if the connect function needed to allocate a resource or memory that is assumed to be present and without which the function cannot succeed OR RECOVER, rethrowing a bad_alloc (for example) or translating it into a context-useful exception would be quite proper since that case really IS exceptional. However, even if a connect function were to fail because it could not allocate some memory (perhaps it never even got as far as trying the connection), I might still lean toward treating that as only an error return if the function can deal with it without putting its object into an unrecoverably inconsistent state. The key is that the function CAN RECOVER... exceptions should be reserved for the out-of-the-blue, unexpected conditions where the function has little choice but to give up and quit. Frankly, I avoid using exceptions. I don't go so far as to mandate using the (nothrow) forms on my projects, but these days I am certainly leaning toward promoting even that in those pieces of code where memory errors are not disasters and should be recoverable. Without going off on a long tangent, one thing I intensely dislike about exceptions is that they introduce myriad invisible control flows into your code, making it darned near impossible to generate test cases that actually do exercise all code paths when exceptions are frequently/widely used. I'll grant that they make recovering from truly exceptional errors more elegant in some cases, no question, but no one should think -- as some seem to -- that exceptions are the solution to all problems and ever so much better than error return codes, or even that they're particularly equal with error codes. The common argument (I would say myth) is that exceptions let you put all your error handling in one place -- this is untrue. For one thing, exceptions aren't supposed to be used for errors. For another, see the related GotW thread on exception safety and how you can easily end up putting try/catch around lots of small operations in the same function in order to make the whole function exception-safe, which is tantamount to degenerating to checking and handling individual return values except that it's a lot more expensive and can be less readable. Overall, my experience is that many libraries and perhaps most programmers grossly overuse exceptions today much as many libraries grossly overused operator overloading three years ago before people generally got a handle on what 'decent normal practice' should be. For example, I remember hearing about one library where to add a control to a window you wrote something like: MyWindow w; MyControl c; ... w + c; /* yuck! */ DON'T try this at home, it'll rot your teeth and has at least 470 calories.