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 <zabluda@math.psu.edu>

>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.

<rant>

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.

</rant>

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.

