This is like saying "If you didn't expect to get stabbed while walking
down the street, then why does the hospital need an emergency room?
An exception is essentially an emergency.
I think that my being stabbed in the street is definitely something
that could occur, but probably not something that would occur.
You said "errors that you don't expect could occur". It's possible you
meant "errors that you don't expect would occur". That's quite a
difference, although the latter still has the problem of being vague
about the level of probability of occurance at which exceptions become
preferable to return codes. And even if you quatified the
probablility, I still don't think that's the criterion for choosing
between the two means of error handling.
The definition of an emergency is something that we know might occur
but can't be predicted. According to Webster "an unforeseen
combination of circumstances".
Clearly that definition isn't appropriate here. You have forseen the
"emergency" otherwise you wouldn't be writing an exception handler to
deal with it.
I really don't think using exceptions for all error cases is a very
good idea.
Neither do I, and I didn't day that. I said they allow you to cleanly
separate error handling code from other code. If the error handling
code does not need to be separated, the ability to separate it cleanly
is not relevant.
If someone logs in and enters a bad password, you are
going to throw an exception? That is hardly "unforeseen".
I might, or I might not. Whether it is forseen or not is going to play
less of a part in that decision than whether the code that handles the
error is logically and physically (e.g. in call stack terms) distant
from the code that detects the error - or to put it another way, will
using exceptions instead of return codes lead to more readable or less
readable code? I suspect for an incorrect password where the responce
is to prompt the user to try again, the error handling code would be
in the same place so exceptions would offer no advantage. On the other
hand, the code to handle the situation where the password is incorrect
three times in a row and the user is locked out could be separate and
in this case using an exception might lead to cleaner code.
We can
debate endlessly about what might be "foreseen" and what might not be
"foreseen".
Indeed we can, and people do. And it is because of this endless debate
that never reaches a satisfactory conclusion that I think the
principle you brought up is not helpful.
We typically write a boolean function (that returns a
boolean value.) Such a function should not be replaced by a void
function that throws an exception, IMO.
If you have several such functions, calling each other down to a
number of levels, and some failures need to be reported all the way
back up the call stack, you end up with precisely the nightmare of
nested ifs and so on that your original question was looking for a
solution to. In this situation, exceptions *are* the solution.
Multiple ways work, and
exceptions can be made to work for all error checking, but this was
not the point of my post.
Nor mine.
That sounds like an awful lot of overhead for some very simple
things. I am reading an article by Alexandrescu, mentioned in a
previous post in this thread. I think I would tend to agree with his
point: "This approach works just fine, but in the real world, it turns
out not to be that neat. You must write a bunch of little classes to
support this idiom. Extra classes mean extra code to write,
intellectual overhead, and additional entries to your class browser.
Moreover, it turns out there are lots of places where you must deal
with exception safety. Let's face it, adding a new class every so
often just for undoing an arbitrary operation in its destructor is not
the most productive."
I've only scanned it just now (I have read it beofer but I don't
recall the full detail), but it looks like that article is talking
about the extra workload involved in achieving the strong vs basic
level of exception safety. I was talking about cleaning up resources
for which failure to clean up would lead to a violation of the basic
exception safety guarantee (e.g. leaking memory, file handles etc.) -
which I think is *always* a bad thing and to which RAII is the general
solution.
The further point is that, unless you are very careful about the code
in your function (including what other functions it calls, whether
your own, third party or standard library), ensuring you have exactly
one return statement, at the end of the function, is not sufficient to
ensure a single exit point. If the "do some cleanup" code is
essential, putting it at the end of the function, immediately
preceding the return, is not appropriate unless you can be certain of
reaching that point in your function without an exception being
thrown.
Whether for any particular piece of code you want to go up from basic
to strong exception safety is a decision to be made on a case by case
basis. It has costs and benefits that cannot be generalised.
Gavin Deane