473,398 Members | 2,403 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Error handling idioms

I'm interested in an idiom for handling errors in functions without
using traditional nested ifs, because I think that can be very awkward
and difficult to maintain, when the number of error checks gets about
3 or so. It also gets very awkward in nested loops, where you want to
check for normal loop processing in the loop condition, not errors.
Yes, you could put some generic exit flag in the loop condition, but
when you're simply done if you find an error, it's much more
straightforward to simply leave all of it.

Exceptions would work, but that is inconsistent with the principle
that exceptions be used for exceptional cases, i.e. errors that you
don't expect could occur.

Basically what I have in mind is something using multiple return
points from a function and possibly gotos (both inconsistent with
traditional structured programming).

This seems good to me - thoughts? Further links for reading?

bool f()
{
if (error condition)
goto ERROR_RETURN;

// do stuff

for ...
{
for ...
{
// do stuff
if (error condition)
goto ERROR_RETURN;
}
}
if (error condition)
goto ERROR_RETURN;

return true;

ERROR_RETURN:
// do some cleanup
return false;
}

Mar 2 '07 #1
35 3726
* je******@yahoo.com:
I'm interested in an idiom for handling errors in functions without
using traditional nested ifs, because I think that can be very awkward
and difficult to maintain, when the number of error checks gets about
3 or so. It also gets very awkward in nested loops, where you want to
check for normal loop processing in the loop condition, not errors.
Yes, you could put some generic exit flag in the loop condition, but
when you're simply done if you find an error, it's much more
straightforward to simply leave all of it.

Exceptions would work, but that is inconsistent with the principle
that exceptions be used for exceptional cases, i.e. errors that you
don't expect could occur.
Don't let silly principles get in the way of practicality.

Basically what I have in mind is something using multiple return
points from a function and possibly gotos (both inconsistent with
traditional structured programming).
Single-entry-multiple-exit (SEME) is advocated by many C++ experts,
including Andrei Alexandrescu.

Some people (e.g. me) have argued to the contrary.

But that's just to flesh out possible shortcomings; don't let silly
principles get in the way of practicality.
This seems good to me - thoughts?
The below code is absolutely ungood: it's not exception safe.

Use C++ destructors for cleanup (called RAII).

Then just use 'return' to return.

Further links for reading?
Look up Petru Marginean and Andrei Alexandrescu's scope guard article.

bool f()
{
if (error condition)
goto ERROR_RETURN;

// do stuff

for ...
{
for ...
{
// do stuff
if (error condition)
goto ERROR_RETURN;
}
}
if (error condition)
goto ERROR_RETURN;

return true;

ERROR_RETURN:
// do some cleanup
return false;
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 2 '07 #2
On Mar 2, 9:50 am, "Alf P. Steinbach" <a...@start.nowrote:
>
The below code is absolutely ungood: it's not exception safe.

Use C++ destructors for cleanup (called RAII).
Well that is a good point. My actual code was enclosed in try/catch
blocks, which I left out from the example. I am reading up on RAII
etc., thanks.

Mar 2 '07 #3
On 2 Mar, 14:43, "jeffc...@yahoo.com" <jeffc...@yahoo.comwrote:
I'm interested in an idiom for handling errors in functions without
using traditional nested ifs, because I think that can be very awkward
and difficult to maintain, when the number of error checks gets about
3 or so. It also gets very awkward in nested loops, where you want to
check for normal loop processing in the loop condition, not errors.
Yes, you could put some generic exit flag in the loop condition, but
when you're simply done if you find an error, it's much more
straightforward to simply leave all of it.

Exceptions would work, but that is inconsistent with the principle
that exceptions be used for exceptional cases, i.e. errors that you
don't expect could occur.
What??? That's a ludicrous principle. What is an "error you don't
expect could occur"? If you don't expect a situation to occur why are
you worrying about writing code to handle it? I know that principle
pops up from time to time but I've never yet found anyone who can
explain what it means.

The benefit of exceptions in C++ is that they allow you to cleanly
separate error handling code from the rest of your code.
Basically what I have in mind is something using multiple return
points from a function and possibly gotos (both inconsistent with
traditional structured programming).
Multiple return points - maybe. After all, as soon as expections are a
possibility, single entry-multiple exit is a given. Gotos - not needed
in the way you are using them.
This seems good to me - thoughts? Further links for reading?
Doesn't look good to me.
>
bool f()
{
if (error condition)
goto ERROR_RETURN;
Just return false here. Failed precoditions are a perfectly acceptable
case for multiple return points. Unless, of course, the preconditions
are entirely under the control of the programmer (e.g. don't depend on
user input) in which case a failed precondition is simply a bug, so an
assert might be more appropriate.
// do stuff

for ...
{
for ...
{
// do stuff
if (error condition)
goto ERROR_RETURN;
}
}
If the loop does not neceesarily run for the number of iterations
implied by the for statement, it looks more like a while loop than a
for loop to me.
if (error condition)
goto ERROR_RETURN;

return true;

ERROR_RETURN:
// do some cleanup
"do some cleanup" should NEVER be necessary. All resources that need
cleaning up should be owned by RAII objects which will do the cleaning
up automatically regardless of how and when the function exits.
return false;
Gavin Deane

Mar 2 '07 #4
On Mar 2, 10:24 am, "Gavin Deane" <deane_ga...@hotmail.comwrote:
>
Exceptions would work, but that is inconsistent with the principle
that exceptions be used for exceptional cases, i.e. errors that you
don't expect could occur.

What??? That's a ludicrous principle. What is an "error you don't
expect could occur"? If you don't expect a situation to occur why are
you worrying about writing code to handle it?
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 know that principle
pops up from time to time but I've never yet found anyone who can
explain what it means.
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".
The benefit of exceptions in C++ is that they allow you to cleanly
separate error handling code from the rest of your code.
I really don't think using exceptions for all error cases is a very
good idea. If someone logs in and enters a bad password, you are
going to throw an exception? That is hardly "unforeseen". We can
debate endlessly about what might be "foreseen" and what might not be
"foreseen". 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. Multiple ways work, and
exceptions can be made to work for all error checking, but this was
not the point of my post.
>
"do some cleanup" should NEVER be necessary. All resources that need
cleaning up should be owned by RAII objects which will do the cleaning
up automatically regardless of how and when the function exits.
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."

Mar 2 '07 #5

<je******@yahoo.comwrote in message
news:11**********************@30g2000cwc.googlegro ups.com...
On Mar 2, 10:24 am, "Gavin Deane" <deane_ga...@hotmail.comwrote:
I'm hardly an expert, but here's my 2 cents worth...

>The benefit of exceptions in C++ is that they allow you to cleanly
separate error handling code from the rest of your code.

I really don't think using exceptions for all error cases is a very
good idea. If someone logs in and enters a bad password, you are
going to throw an exception? That is hardly "unforeseen". We can
debate endlessly about what might be "foreseen" and what might not be
"foreseen". We typically write a boolean function (that returns a
boolean value.)
Agreed...that's an "expected error" which must be handled appropriately.
There are plenty of these kinds of conditions in which throwing an exception
would be inapprorpriate, particularly since you would have catch the
exception to handle it anyway, which is no different than checking an error
value (just slower).

>Such a function should not be replaced by a void
function that throws an exception, IMO. Multiple ways work, and
exceptions can be made to work for all error checking, but this was
not the point of my post.
Also true. On the other hand, if every function returns an error code, then
you have to check for, and handle, every possible failure (or ignore the
return codes which, I suspect, we all do far too often!). I think it was
Steve Maguire in his book "Writing Solid Code" that suggested that you write
functions that can't fail. Obviously, this is an impossible task, but the
spirit of his suggestion can be accomplished by using exceptions. Write
your functions as robustly as possible, then call them *as if* they can't
fail. If they do, let some exception handler further up the call tree take
care of processing the error condition.

>"do some cleanup" should NEVER be necessary. All resources that need
cleaning up should be owned by RAII objects which will do the cleaning
up automatically regardless of how and when the function exits.

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."
True again. But for non-trivial cases, it is much easier and much safer to
write an RAII class to handle cleanup. If you have to write the cleanup
code anyway, you might as well do it once, encapsulate it, get it right, and
never worry about it again. And if your code does encounter a true
exception, you're that much better off.

- Dennis
Mar 2 '07 #6
On Mar 2, 12:05 pm, "Dennis Jones" <nos...@nospam.comwrote:
>
Such a function should not be replaced by a void
function that throws an exception, IMO. Multiple ways work, and
exceptions can be made to work for all error checking, but this was
not the point of my post.

Also true. On the other hand, if every function returns an error code, then
you have to check for, and handle, every possible failure (or ignore the
return codes which, I suspect, we all do far too often!).
Right. I can't say I've comfortably settled into a coherent
philosophy yet....
Mar 2 '07 #7
On 2 Mar, 15:43, "jeffc...@yahoo.com" <jeffc...@yahoo.comwrote:
On Mar 2, 10:24 am, "Gavin Deane" <deane_ga...@hotmail.comwrote:
Exceptions would work, but that is inconsistent with the principle
that exceptions be used for exceptional cases, i.e. errors that you
don't expect could occur.
What??? That's a ludicrous principle. What is an "error you don't
expect could occur"? If you don't expect a situation to occur why are
you worrying about writing code to handle it?

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.
I know that principle
pops up from time to time but I've never yet found anyone who can
explain what it means.

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.
The benefit of exceptions in C++ is that they allow you to cleanly
separate error handling code from the rest of your code.

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.
"do some cleanup" should NEVER be necessary. All resources that need
cleaning up should be owned by RAII objects which will do the cleaning
up automatically regardless of how and when the function exits.

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

Mar 2 '07 #8
On Mar 2, 3:16 pm, "Gavin Deane" <deane_ga...@hotmail.comwrote:
>
You said "errors that you don't expect could occur". It's possible you
meant "errors that you don't expect would occur".
Maybe I did, can't remember. But one recommended usage of assertions
is covering cases that you think are really silly, because you assume
they can't happen. So in theory the idea has some sort of merit.
Obviously if it's truly mathematically impossible for something to
happen, then it need not be considered.
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 suppose we're being pedantic, but you haven't explained the
existence of "Emergency Rooms" at hospitals. If you call them
misnomers, still there are many "emergency procedures" in place in the
world to handle events that are correctly defined as emergencies.

That doesn't prove exceptions are or should be emergencies. I have no
problem with using exceptions for basic error handling if it's part of
a consistent strategy, as you seem to use them. I'm just saying the
original principle I described exists (whether or not I or you agree
with it), and the idea that it's a debatable principle doesn't mean
it's invalid.

Mar 2 '07 #9
On 2 Mar, 22:35, "jeffc...@yahoo.com" <jeffc...@yahoo.comwrote:
On Mar 2, 3:16 pm, "Gavin Deane" <deane_ga...@hotmail.comwrote:
I suppose we're being pedantic, but you haven't explained the
existence of "Emergency Rooms" at hospitals. If you call them
misnomers, still there are many "emergency procedures" in place in the
world to handle events that are correctly defined as emergencies.
I can't explain their existence by analogy to C++ error handling
mechanisms because I simply don't see a connection. I am aware of the
"use exceptions for exceptional circumstances" idea, but I am not
aware of anything behind the idea - just those headline words. There
is nothing in my personal experience of programming, maintaining or
reading what other people have to say that has given me any inkling of
how those who advocate the idea intend that I should distinguish, on a
case by case basis, between cases where exceptions are appropriate and
cases where they aren't. On the other hand, while not being
mathematically quatifiable, simplicity and readability of code are
familiar concepts usually at the forefront of my mind. I am well aware
of what they mean, well aware of their advantages and well aware of
how, in some situations, using exceptions for error handling can help
me achieve them.
That doesn't prove exceptions are or should be emergencies. I have no
problem with using exceptions for basic error handling if it's part of
a consistent strategy, as you seem to use them. I'm just saying the
original principle I described exists (whether or not I or you agree
with it), and the idea that it's a debatable principle doesn't mean
it's invalid.
I question its validity not because I am skeptical of the benefits of
applying the principle, but because, far more fundamentally, I am
skeptical that anyone can tell me *how* to consistently apply the
principle so that I may even assess its benefits. My question is
whether there is any meaning (not necessarily mathematically precise,
but clear enough to be communicated reliably from one person to
another) behind the slogan "use exceptions for exceptional
circumstances". If there is, I haven't seen it and I don't think it's
for want of looking.

Gavin Deane

Mar 3 '07 #10
Gavin Deane wrote:
>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.
I disagree. Assuming that the boolean function is doing what it's
supposed to. In that it tries something and reports success/failure.
Apparently for this case, at that level, either is pretty much as likely
as the other. This isn't a good case for exceptions and shouldn't be
changed to report them.

On the other hand...

Maybe you are calling that function from a file reader that is reading a
format you invented. At this point in the code we could say we know the
format is the expected type we intend to read so failure here is an
exceptional situation. Then at this point we can throw an exception if
the function fails.

This makes your reader (let's assume that's what the function
does..parses something) function usable at both levels...where it could
normally fail and where it isn't normal for it to fail. You have one
level of ifs in both situations and are not required to use an exception
in say ... a dialog handler where it's just ugly.

If you change the function to toss an exception instead of report a
status you tie that function to a particular use. I think the question
of exceptionality is specific to a particular function...not it's clients.
Mar 5 '07 #11
On 5 Mar, 16:04, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
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.

I disagree. Assuming that the boolean function is doing what it's
supposed to. In that it tries something and reports success/failure.
Apparently for this case, at that level, either is pretty much as likely
as the other. This isn't a good case for exceptions and shouldn't be
changed to report them.
I think if success and failure are broadly as likely as each other, it
is unlikely that the response to failure and the response to success
should logically be handled in completely different areas of the code.

Sometimes, the code that performs some action and the code that
handles failure of that action are distant from each other in terms of
program structure, and you need a way to travel that distance when
failure occurs. You could do that by traversing the program structure
one step at a time with return codes, or you could get there in one
clean step by throwing an exception. This is what I mean by
readability being the criterion for deciding between error handling
mechanisms.

But I wouldn't recommend exceptions when the code handling success and
the code handling failure are structurally close. The advantage of
exceptions is that they can move you very cleanly to a different point
in the program structure. If you don't want to go to a different point
in the program structure that's not going to be relevant to you.

Gavin Deane

Mar 5 '07 #12
Gavin Deane wrote:
On 5 Mar, 16:04, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
>>>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.
I disagree. Assuming that the boolean function is doing what it's
supposed to. In that it tries something and reports success/failure.
Apparently for this case, at that level, either is pretty much as likely
as the other. This isn't a good case for exceptions and shouldn't be
changed to report them.

I think if success and failure are broadly as likely as each other, it
is unlikely that the response to failure and the response to success
should logically be handled in completely different areas of the code.
Depends on if failure is an error. If you fail to parse a telephone
number is that an error? When parsing a file that expects there to be a
phone number then probably; when getting user input probably not since
one should expect the user to enter bad values. It is especially not an
error at parse point when you could be using the function in something
like: is it a phone number or an email address?

Use exceptions for error handling. Not all failures are errors.
Mar 5 '07 #13
On 5 Mar, 18:16, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
I think if success and failure are broadly as likely as each other, it
is unlikely that the response to failure and the response to success
should logically be handled in completely different areas of the code.

Depends on if failure is an error. If you fail to parse a telephone
number is that an error? When parsing a file that expects there to be a
phone number then probably; when getting user input probably not since
one should expect the user to enter bad values. It is especially not an
error at parse point when you could be using the function in something
like: is it a phone number or an email address?

Use exceptions for error handling. Not all failures are errors.
I have no desire to use exceptions for everything. The problem I have
with using exceptions for "errors not failures" or "only in
exceptional circumstances" is knowing what those words mean. In
contrast, I know exactly what readability means because it is a
concept I deal with constantly whenever I am programming.

If I start a new program that involves some file parsing, I don't find
it helpful to think about what probability threshold a particular
class of failure must pass for exceptions to be appropriate, then
assess the actual probability of each class of failure against that
threshold. I do find it helpful to look at the design and identify
areas where the transition from detection of failure to error handling
to appropriate following action is made cleaner by the use of
exceptions than error codes.

The end result is probably the same. It's the thought process in the
decision making that's different, because the "only in exceptional
circumstances" logic doesn't give me any criteria I understand.

Gavin Deane

Mar 5 '07 #14
Gavin Deane wrote:
On 5 Mar, 18:16, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
>>I think if success and failure are broadly as likely as each other, it
is unlikely that the response to failure and the response to success
should logically be handled in completely different areas of the code.
Depends on if failure is an error. If you fail to parse a telephone
number is that an error? When parsing a file that expects there to be a
phone number then probably; when getting user input probably not since
one should expect the user to enter bad values. It is especially not an
error at parse point when you could be using the function in something
like: is it a phone number or an email address?

Use exceptions for error handling. Not all failures are errors.

I have no desire to use exceptions for everything. The problem I have
with using exceptions for "errors not failures" or "only in
exceptional circumstances" is knowing what those words mean. In
contrast, I know exactly what readability means because it is a
concept I deal with constantly whenever I am programming.

If I start a new program that involves some file parsing, I don't find
it helpful to think about what probability threshold a particular
class of failure must pass for exceptions to be appropriate, then
assess the actual probability of each class of failure against that
threshold.
It has nothing to do with probability and all to do with semantics.
Failure is either a common occurance or an error. "Readability" is no
less subjective.
Mar 5 '07 #15
On 5 Mar, 23:09, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
If I start a new program that involves some file parsing, I don't find
it helpful to think about what probability threshold a particular
class of failure must pass for exceptions to be appropriate, then
assess the actual probability of each class of failure against that
threshold.

It has nothing to do with probability and all to do with semantics.
Failure is either a common occurance or an error. "Readability" is no
less subjective.
It's no more subjective either. The difference is that I know how to
apply the abstract concept of readability to any arbitrary programming
problem because I am used to thinking in terms of readability as a
matter of course (and, while it is subjective, I seem to be able to
work productively with other people so I must be getting it about
right). On the other hand, I know of no abstract principle that
distinguishes the different properties of a common occurance and an
error.

If you were refactoring some existing code that originally handled
failures with return codes, and you ended up with the handling several
levels higher in the call stack than the detection, with all the
intermediate levels made more complex with branches and conditions
depending on the state of these codes, would you refuse to even
consider exceptions solely because you've categorised this failure as
a common occurance not an error?

Gavin Deane

Mar 6 '07 #16
Gavin Deane wrote:
On 5 Mar, 23:09, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
>>If I start a new program that involves some file parsing, I don't find
it helpful to think about what probability threshold a particular
class of failure must pass for exceptions to be appropriate, then
assess the actual probability of each class of failure against that
threshold.
It has nothing to do with probability and all to do with semantics.
Failure is either a common occurance or an error. "Readability" is no
less subjective.

It's no more subjective either. The difference is that I know how to
apply the abstract concept of readability to any arbitrary programming
problem because I am used to thinking in terms of readability as a
matter of course (and, while it is subjective, I seem to be able to
work productively with other people so I must be getting it about
right). On the other hand, I know of no abstract principle that
distinguishes the different properties of a common occurance and an
error.

If you were refactoring some existing code that originally handled
failures with return codes, and you ended up with the handling several
levels higher in the call stack than the detection, with all the
intermediate levels made more complex with branches and conditions
depending on the state of these codes, would you refuse to even
consider exceptions solely because you've categorised this failure as
a common occurance not an error?
If it isn't an error it has no place being handled like one, no?
Mar 6 '07 #17
On 6 Mar, 20:57, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
If you were refactoring some existing code that originally handled
failures with return codes, and you ended up with the handling several
levels higher in the call stack than the detection, with all the
intermediate levels made more complex with branches and conditions
depending on the state of these codes, would you refuse to even
consider exceptions solely because you've categorised this failure as
a common occurance not an error?

If it isn't an error it has no place being handled like one, no?
If I'm understanding you correctly, you're logic appears to be:

Exceptions should only be used to handle errors.
The situation being handled is a common occurance, not an error.
Therefore it is not appropriate to handle this situation with an
exception.

Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances. And that's before we've even got
into the question of needing to identify the generic properties that
distinguish the two.

The dialogue always goes like this...

Me: I consider using exceptions in any situation where their use makes
code clearer to understand.
Somebody else: Oh no, you can't do that. Exceptions are only for use
in exceptional circumstances.
Me: Why?
Somebody else: ... [blank look] ...

And that's it. I'm very willing to consider any response to the "Why?"
question, but I've never encountered one to consider.

Gavin Deane

Mar 7 '07 #18
Gavin Deane wrote:
On 6 Mar, 20:57, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
If you were refactoring some existing code that originally handled
failures with return codes, and you ended up with the handling several
levels higher in the call stack than the detection, with all the
intermediate levels made more complex with branches and conditions
depending on the state of these codes, would you refuse to even
consider exceptions solely because you've categorised this failure as
a common occurance not an error?

If it isn't an error it has no place being handled like one, no?

If I'm understanding you correctly, you're logic appears to be:

Exceptions should only be used to handle errors.
The situation being handled is a common occurance, not an error.
Therefore it is not appropriate to handle this situation with an
exception.

Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances. And that's before we've even got
into the question of needing to identify the generic properties that
distinguish the two.

The dialogue always goes like this...

Me: I consider using exceptions in any situation where their use makes
code clearer to understand.
Somebody else: Oh no, you can't do that. Exceptions are only for use
in exceptional circumstances.
Me: Why?
Somebody else: ... [blank look] ...

And that's it. I'm very willing to consider any response to the "Why?"
question, but I've never encountered one to consider.
Since I do not subscribe to the point you question, I might not be
well-posed to answer your call. I will try nonetheless. I know the
following reasons:

a) Code is meant to communicate intent. Since, for better or worse,
exceptions have been popularized by the powers that be as a mechanism for
error handling only, it is wise to follow that rule. Violations are bound
to create misleading expectations in those reading the code.

b) Similarly, because of the wide-spread perception that exceptions are
rare, many compilers tend to heavily optimize for the non-throw path of
control flow. Thus, using exceptions can be quite expensive.

c) The try-throw-catch mechanism is a glorified goto, except that it is even
worse: with a goto, at least you know where you jump. The dangers posed by
exceptions for maintainable programming are quite similar to those of goto.
Try-throw-catch introduces global dependencies in your code, i.e., it
becomes hard to understand the program in local terms, like what is going
on in the few lines on my screen. Therefore, strict coding guidelines
should accompany the use of exceptions. The rule to use them for
error-reporting only is a successful proposal in this regard. Weakening it
to: "write code that is easy to understand" is too permissive and will lead
down a slippery slope (as it does with goto). However, it is true that a
restrictive criterion can be inconvenient at times. This is just the price
you have to pay to confine the threat.
As for myself, I think that rules regarding try-throw-catch are coding
styles and should be local to a project, shop, community, etc. I don't
think that there is any valid technical reason to restrict try-throw-catch
to error handling. It has become a tradition, and following that tradition
is by and large a good thing if you want to work smoothly with others. Had
the C++ community set out to find interesting ways of using exceptions (as
it has done with templates), compilers would optimize differently and your
fellow programmers would read your code differently. But this has not
happened.
Best

Kai-Uwe Bux
Mar 7 '07 #19
Gavin Deane wrote:
Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances.
You said it yourself.

So that error handling and normal program logic are not intermingled.

Second, there's the performance issue...exceptions can throw slow and do
in at least one common implementation.
Mar 7 '07 #20
On 7 Mar, 00:45, Noah Roberts <u...@example.netwrote:
GavinDeanewrote:
Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances.

You said it yourself.

So that error handling and normal program logic are not intermingled.
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.

A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.

"Normal program logic" is the path taken in the absence of any
failures.

Using those definitions, I use exceptions when the design calls for
handling of a particular failure to be separated from normal program
logic, regardless of whether that failure is an error or a common
occurance. I don't do that because I have a penchant for exceptions
and I want to use them wherever possible. I do it because, in desiging
my software, I have already identified the points where failuire
handling needs to be separated from normal program logic.

I don't know how to make the decision based on whether a particular
failure is a common occurance or an error, because I don't know what
are the generic cirteria that distinguish the two across all
programming problems. That is why I was only able to define "error"
and "common occurance" above by reference to existing examples. But my
definitions above do not help me decide whether a particular failure
is an error or a common occurance when I am tackling a *new* problem.

Two examples of things I am unlikely to do:

Introduce branches and conditions into a group of functions so I can
pass a return code indicating failure several layers up the call stack
when I could get there in one go with an exception, even if someone
argues that that failure is a common occurance.

Throw and catch an exception within the same function[*] if a
particular failure occurs, even if someone argues that that failure is
an error. (Although I suppose I might consider doing this if it's a
vast, monolithic, maintenace nightmare of a function where it is
possible to be very distant from the detection of the failure yet
still within the same function. In an ideal world such things should
never happen, but in the real world they do).
Second, there's the performance issue...exceptions can throw slow and do
in at least one common implementation.
Indeed, but that's an orthogonal consideration as susceptible to
premature optimisation as any other performance issue.

Gavin Deane

Mar 7 '07 #21
Gavin Deane wrote:
On 7 Mar, 00:45, Noah Roberts <u...@example.netwrote:
>GavinDeanewrote:
>>Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances.
You said it yourself.

So that error handling and normal program logic are not intermingled.

There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.

A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.

"Normal program logic" is the path taken in the absence of any
failures.
change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to handle.
Mar 7 '07 #22
On 7 Mar, 17:47, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
On 7 Mar, 00:45, Noah Roberts <u...@example.netwrote:
GavinDeanewrote:
Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances.
You said it yourself.
So that error handling and normal program logic are not intermingled.
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.
A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.
We'll keep the three definitions above.
"Normal program logic" is the path taken in the absence of any
failures.

change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to handle.
You've missed the point of why I provided these definitions. My
argument needs a name for the concept of the path taken in the absence
of any failures. If you don't like "normal program logic" as the name
for that concept that's fine, I'll call it something else. How about
"non-failure program logic"? It's a bit more cumbersome, but I do need
a name for the concept.

Change "normal program logic" to "non-failure program logic" in my
previous post.

Gavin Deane

Mar 7 '07 #23
Gavin Deane wrote:
On 7 Mar, 17:47, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
>>On 7 Mar, 00:45, Noah Roberts <u...@example.netwrote:
GavinDeanewrote:
Impeccable logic, but only if one accepts the premise. That logic
tells me nothing about *why* exceptions should only be used to handle
errors and not common occurances.
You said it yourself.
So that error handling and normal program logic are not intermingled.
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.
A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.

We'll keep the three definitions above.
>>"Normal program logic" is the path taken in the absence of any
failures.
change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to handle.

You've missed the point of why I provided these definitions.
No, I think you missed the point. Simple failure belongs in program
logic. X != expected value is not an exceptional event. User entering
the wrong password...also not an error. These are failures and belong
in the normal program flow.
Mar 7 '07 #24
On 7 Mar, 21:02, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
On 7 Mar, 17:47, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.
A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.
We'll keep the three definitions above.
>"Normal program logic" is the path taken in the absence of any
failures.
change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to handle.
You've missed the point of why I provided these definitions.

No, I think you missed the point. Simple failure belongs in program
logic. X != expected value is not an exceptional event. User entering
the wrong password...also not an error. These are failures and belong
in the normal program flow.
Depends what you mean by "normal". I meant something else. I was aware
that I was using the phrase "normal program logic" to mean something
very specific, which is why I was careful to define what I meant.

You tried to tell me that my definition of "normal program logic" was
incorrect. That was a non sequitur because, for the purposes of my
argument, "normal program logic" was a term *I* was defining.

Recognising that despite my careful definition there was scope for
confusion because I had used a term that already meant somthing else
to you, I changed the name of the concept from "normal program logic"
to "non-failure program logic". The definition is the same but
hopefully the new name is unfamiliar and so you have no preconceived
ideas about its meaning.

So, if you want to understand my argument, re-read my post up-thread,
substituting "non-failure program logic" for "normal program logic"

Gavin Deane

Mar 7 '07 #25
Gavin Deane wrote:
On 7 Mar, 21:02, Noah Roberts <u...@example.netwrote:
>Gavin Deane wrote:
>>On 7 Mar, 17:47, Noah Roberts <u...@example.netwrote:
Gavin Deane wrote:
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.
A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.
We'll keep the three definitions above.
"Normal program logic" is the path taken in the absence of any
failures.
change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to handle.
You've missed the point of why I provided these definitions.
No, I think you missed the point. Simple failure belongs in program
logic. X != expected value is not an exceptional event. User entering
the wrong password...also not an error. These are failures and belong
in the normal program flow.

Depends what you mean by "normal". I meant something else. I was aware
that I was using the phrase "normal program logic" to mean something
very specific, which is why I was careful to define what I meant.

You tried to tell me that my definition of "normal program logic" was
incorrect. That was a non sequitur because, for the purposes of my
argument, "normal program logic" was a term *I* was defining.
Shen me? Wo bu zhi dao ni gao su wo.
Mar 7 '07 #26
On 7 Mar, 00:41, Kai-Uwe Bux <jkherci...@gmx.netwrote:

I posted a reply yesterday but it's not appeared yet. A delay that
long between posting and seeing the post is unusual through Google
Groups so I'll try again. Apologies for the double post if the first
one eventually appears.
Since I do not subscribe to the point you question, I might not be
well-posed to answer your call. I will try nonetheless. I know the
following reasons:

a) Code is meant to communicate intent. Since, for better or worse,
exceptions have been popularized by the powers that be as a mechanism for
error handling only, it is wise to follow that rule. Violations are bound
to create misleading expectations in those reading the code.
I absolutely agree with the principle of code communicating intent.
However, for someone to say "exceptions are for error handling only"
is meaningless without a definition of "error". Without that, there is
no common understanding of intent that can be mis-communicated. "Your
code confused me for a while there because you were using an exception
for a situation that wasn't an error" or "Your code confused me
because you used something other than an exception to handle that
error" are only valid compliants if we all have the same
understanding, generically, of what is and what isn't an error.

The question I have is, what are the generic properties or criteria,
applicable across all programming problems, that distinguish events
for which exceptions are appropriate from events for which exceptions
are not appropriate. It is the lack of any answer to *this* question
that means I don't find a statement like "exceptions are for error
handling only" at all useful, particularly when trying to give general
advice on when to use exceptions to someone learning the language.

The only answer prevalent seems to be "an error is any situation that
isn't normal" which moves us no further. It just changes the question
from "Please define error" to "OK, error == !normal. Please define
normal".
b) Similarly, because of the wide-spread perception that exceptions are
rare, many compilers tend to heavily optimize for the non-throw path of
control flow. Thus, using exceptions can be quite expensive.
I don't disagree there either. And I don't think my approach leads to
a particularly more widespread use of exceptions. The difference is
that it's an approach based on concepts I understand rather than
concepts I don't understand and nobody can explain to me. My point is
not so much about when to use exceptions, but more about how to
explain to someone who doesn't know, when to use exceptions.

There is the issue of premature optimisation too of course. In
general, I won't worry about the performance hit unless and until it's
shown to be a problem. If exceptions are known to be quite expensive,
deciding in advance not to use them all over the place is probably not
premature optimisation - it's sensible. But as I say, I'm not
suggesting using them all over the place.
c) The try-throw-catch mechanism is a glorified goto, except that it is even
worse: with a goto, at least you know where you jump. The dangers posed by
exceptions for maintainable programming are quite similar to those of goto.
Try-throw-catch introduces global dependencies in your code, i.e., it
becomes hard to understand the program in local terms, like what is going
on in the few lines on my screen. Therefore, strict coding guidelines
should accompany the use of exceptions. The rule to use them for
error-reporting only is a successful proposal in this regard. Weakening it
to: "write code that is easy to understand" is too permissive and will lead
down a slippery slope (as it does with goto). However, it is true that a
restrictive criterion can be inconvenient at times. This is just the price
you have to pay to confine the threat.
Bear in mind that my criterion for considering exceptions is that I
have already identified a need to get from one point in the program
structure to some other non-local point in the program structure. It
is already a given that you will not be able to fully understand this
part of the program in local terms by looking at the few lines on your
screen. The only question that remains is "Since I have to jump from
this point here to that point over there, what is the cleanest way of
doing that?". Options might be, for example, throw an exception,
introduce return codes to a family of functions, goto, refactor the
code. I say, if the answer is "exceptions are cleanest" then use
exceptions. I finish the decision process and it doesn't matter that
nobody can explain to me what's an "error" and what's "normal" because
I haven't had to make any decisions based on that distinction.

It is because I generally try and avoid jumping around the program
structure like this (for the reasons you mention) that I end up using
exceptions rarely.

Gavin Deane

Mar 8 '07 #27
Gavin Deane wrote:
On 7 Mar, 00:41, Kai-Uwe Bux <jkherci...@gmx.netwrote:

I posted a reply yesterday but it's not appeared yet. A delay that
long between posting and seeing the post is unusual through Google
Groups so I'll try again. Apologies for the double post if the first
one eventually appears.
>Since I do not subscribe to the point you question, I might not be
well-posed to answer your call. I will try nonetheless. I know the
following reasons:

a) Code is meant to communicate intent. Since, for better or worse,
exceptions have been popularized by the powers that be as a mechanism for
error handling only, it is wise to follow that rule. Violations are bound
to create misleading expectations in those reading the code.

I absolutely agree with the principle of code communicating intent.
However, for someone to say "exceptions are for error handling only"
is meaningless without a definition of "error". Without that, there is
no common understanding of intent that can be mis-communicated. "Your
code confused me for a while there because you were using an exception
for a situation that wasn't an error" or "Your code confused me
because you used something other than an exception to handle that
error" are only valid compliants if we all have the same
understanding, generically, of what is and what isn't an error.
Actually, there is no need for a definition of "error" to make the rule

Use exceptions for error-handling only

work. If everybody obeys that rule, the use of an exception in the code will
communicate that the author considered the condition an error. Whether you
agree with that assesment or not is immaterial, the communication of intent
was nonetheless successful.

One could even go so far to say that we need a language feature reserved for
error handling precisely because reasonable people can disagree on what an
error is so that a programmer can express his assesment of a particular
situation (i.e., whether a certain condition is an error or not) in code.
If we had a clear-cut criterion, we would not need to communicate that X is
an error because the reader could figure that out by himself.

All that is needed is that error is a concept that can be understood and
agreed/disagreed upon in examples and concrete cases: it is always concrete
cases about which we communicate when writing code.

The question I have is, what are the generic properties or criteria,
applicable across all programming problems, that distinguish events
for which exceptions are appropriate from events for which exceptions
are not appropriate. It is the lack of any answer to *this* question
that means I don't find a statement like "exceptions are for error
handling only" at all useful, particularly when trying to give general
advice on when to use exceptions to someone learning the language.

The only answer prevalent seems to be "an error is any situation that
isn't normal" which moves us no further. It just changes the question
from "Please define error" to "OK, error == !normal. Please define
normal".
"Error" is a concept that I would only illustrate by examples. I cannot
really define the notion of a smooth texture. But I can recognize one, and
I am confident that I could teach someone to recognize smooth textures.
Definitions are not the only way to introduce concepts. What about "error"
is it that gives you trouble? Could it be that you are reading too much
into the recommendation. The way I understand it (as far as communicating
intend goes) is:

Use exceptions to make clear that the handled condition is considered
an error.

That does not pre-suppose that there is a definition of "error". It just
pre-supposes that the addressee of the recommendation has an understanding
of what _he_ considers an error _within_ the context of a particular
program. Then he uses exceptions to signal to others that condition X
counts as an error in the context of program Y.
[(b) snipped for lack of disagreement]
>c) The try-throw-catch mechanism is a glorified goto, except that it is
even worse: with a goto, at least you know where you jump. The dangers
posed by exceptions for maintainable programming are quite similar to
those of goto. Try-throw-catch introduces global dependencies in your
code, i.e., it becomes hard to understand the program in local terms,
like what is going on in the few lines on my screen. Therefore, strict
coding guidelines should accompany the use of exceptions. The rule to use
them for error-reporting only is a successful proposal in this regard.
Weakening it to: "write code that is easy to understand" is too
permissive and will lead down a slippery slope (as it does with goto).
However, it is true that a restrictive criterion can be inconvenient at
times. This is just the price you have to pay to confine the threat.

Bear in mind that my criterion for considering exceptions is that I
have already identified a need to get from one point in the program
structure to some other non-local point in the program structure. It
is already a given that you will not be able to fully understand this
part of the program in local terms by looking at the few lines on your
screen. The only question that remains is "Since I have to jump from
this point here to that point over there, what is the cleanest way of
doing that?". Options might be, for example, throw an exception,
introduce return codes to a family of functions, goto, refactor the
code. I say, if the answer is "exceptions are cleanest" then use
exceptions. I finish the decision process and it doesn't matter that
nobody can explain to me what's an "error" and what's "normal" because
I haven't had to make any decisions based on that distinction.

It is because I generally try and avoid jumping around the program
structure like this (for the reasons you mention) that I end up using
exceptions rarely.
The question here is not so much whether this decision making process works
for you. It is more about whether recommending this decision making process
to others is wise. It could be that your personal understanding of what
is "cleanest" leads you to use exceptions only rarely. However, I wonder
whether others programmers understanding of what counts as clean is
sufficiently similar and will prevent them from using exceptions
dangerously often. The problem is, of course, that we make decisions about
exceptions many times in a larger program; each decision is well-justified
at the time; but still they might add up to a horrible mess in the end.
Ultimately, I feel that no rule can replace wisdom and experience. I like to
experiment with programming styles, and I confess to trying out gotos and
exceptions in places considered inappropriate by most programmers.
Sometimes I end up with a convoluted result and it is precisely in those
cases where I learn something (assesing which choices were bad). I think,
we should not try to protect beginners from such mistakes by giving them
rules to follow. Maybe, it would be better to tell them that they need a
critical attitude toward their code and should be prepared for major
rewrites as their skills mature over time.
Best

Kai-Uwe Bux
Mar 8 '07 #28

"Noah Roberts" <us**@example.netwrote in message
news:es**********@aioe.org...
Gavin Deane wrote:
>On 7 Mar, 17:47, Noah Roberts <u...@example.netwrote:
>>Gavin Deane wrote:
On 7 Mar, 00:45, Noah Roberts <u...@example.netwrote:
GavinDeanewrote:
>Impeccable logic, but only if one accepts the premise. That logic
>tells me nothing about *why* exceptions should only be used to handle
>errors and not common occurances.
You said it yourself.
So that error handling and normal program logic are not intermingled.
There are too many vaguely defined terms here. Let's fix that. For the
remainder of this post I will use the following definitions.
A "failure" is when you try something and don't get the right result.
"Failures" fall into two categories. Using examples from up-thread:
A "common occurance" is a failure like the user spelling their
password incorrectly.
An "error" is a failure like finding incorrectly formatted data in a
file my program created.

We'll keep the three definitions above.
>>>"Normal program logic" is the path taken in the absence of any
failures.
change failures to errors here. Trying something and failing is not
always an error and thus falls into the "normal program logic" to
handle.

You've missed the point of why I provided these definitions.

No, I think you missed the point. Simple failure belongs in program
logic. X != expected value is not an exceptional event. User entering
the wrong password...also not an error. These are failures and belong in
the normal program flow.
OK, I'll go out on a limb and add a few thoughts (since the thread at this
has had me sitting here thinking about the issues for a few minutes now)...

Is getting invalid input data from a user an error? Well it depends on your
definitions in the area of error processing. Someone may say it is not an
"error" because they reserve that term for another category of conditions.
They may say it is "simple failure" or something. I personally would
categorize it as "user error" and handle it appropriately (dialog warning
box, lockout after 3 unsuccessful tries, etc.). I'm OK with calling all
kinds of things like that "errors" as long as the category or type of the
error is given also: "user error", "user input error", "assertion error",
etc.

Now let's example with a contrasting kind of error: a program requiring a
..ini file from which to read initialization information finds that the file
does not exist (!). The program gets installed with a default .ini file and
we know that so something is severely amuck (perhaps the user was mucking
around in folders where he should not have been and, yes, deleted the
file!). Well obviously the program cannot startup without the .ini file.
That it is missing in action is exceptional.

In the above example, I tried to convey a "severe error" or something
"exceptional", very "not expected nor likely". Well it's obvious then C++
exceptions should be used right? I mean, we have an exceptional scenario and
a set of mechanisms in C++ has the same name ("exceptions") so surely that
is what we want to use in this scenario. Well if that's the error processing
design you've chosen, by all means use it if you want to, but return codes
would work just as well. The point I am trying to make is that, I think, the
choice made to name the new error processing mechanism in C++ was not
necessarily chosen to reflect under what conditions it should be used. Sure,
the "can't return an error code from a constructor" scenario is a tricky
problem to solve, hence it is exceptional, and that's probably how the
mechanism got its name. Realize though that the mechanism was pretty much
required to make the language work cleanly (surely there are alternatives
but the "non local goto" was seen as the best solution and it's not like
there wasn't prior common practice aka setjmp/longjmp).

Making a long story short: having exceptional circumstances, such as the
..ini file missing, does not map onto "that's what C++ exceptions are for".
If the situation warrants it, such as constructor error, or if you deem the
mechanisms otherwise worthy, go ahead and use them for they are at your
disposal. There is no hard and fast rule about when to use any mechanism in
the application programming space based upon "error severity" and such.
Certainly encountering "exceptional circumstances" does not necessarily
warrant using the C++ exception MECHANISMs. If you're trying to process
error in operators and constructors and such, it may be the easiest way and
the mechanisms are designed with that in mind (in addition to other
requirements such as cross-library error handling).

The name given to the C++ error handling mechanisms is probably unfortunate
in that it often confuses. If I'm pretty much on track with the above and
you accept it as so, than you realize that what mechanisms you use don't
really matter. Your taxonomy of errors and how to handle them and that you
do handle them is more important: how to handle user input errors (as
described above maybe), how to handle "exceptional circumstances"/"severe
errors" (msg box, log, notify, abort, maybe), etc. And your
taxonomy/categorization and handling will to some degree (probably to a
large degree) be application-specific.

Primarily, the key is to recognize that the C++ error processing mechanisms
were developed out of need to make the language work like they wanted it to
and the "exception" name given to those mechanisms shouldn't be over-thought
(made overly significant) when applying them. If the mechanisms will work
for you and you decide that that is the way to go, use them. If not, don't.
Substituting "C++ exceptions" with "the C++ error processing mechanism set"
may be helpful. Things like "belongs in the program flow" seem to be just
personal preference or one specific implementation. Searching for absolute
rules (the "right way") is futile I think, as there is more than one way to
skin a cat.

I think a discussion about categorization of errors and handling strategies
would be much more interesting than this one of which processing mechanisms
to use. That of course would belong in comp.programming and not in
comp.lang.c++ though. Another good discussion would be "Alternatives to
RAII/exceptions" or "RAII without exceptions".

John
Mar 10 '07 #29
On 8 Mar, 13:43, Kai-Uwe Bux <jkherci...@gmx.netwrote:
GavinDeanewrote:
Actually, there is no need for a definition of "error" to make the rule

Use exceptions for error-handling only

work. If everybody obeys that rule, the use of an exception in the code will
communicate that the author considered the condition an error. Whether you
agree with that assesment or not is immaterial, the communication of intent
was nonetheless successful.
I can see your logic. I think I would have to reflect on it a while
before I could agree on the usefulness of communicating an intent when
you still leave outstanding the question of *why*. If I see an
exception in your code I know that you considered that situation to be
an "error" by your personal definition. But if I don't believe the
situation to be an error according to my personal definition, I'm not
sure that's helped me much in getting inside your head.

<snip>
What about "error"
is it that gives you trouble? Could it be that you are reading too much
into the recommendation. The way I understand it (as far as communicating
intend goes) is:

Use exceptions to make clear that the handled condition is considered
an error.
As I say, without a common understanding of the definition of error,
there is nothing to explain *why* you think that condition is an error
and so, unless I happen to agree with you, I still haven't been able
to fully appreciate how you were thinking when you wrote that code.

There's another interesting point here if. If you use exceptions for
handling errors, that suggests that you are in a position to decide
which conditions will be handled by exceptions before you even start
to think about the structure of your program. By my approach I can't
do that, and I wouldn't want to.

I wouldn't want to because, as suggested elsethread, I don't want to
use an exception for a condition that is handled locally, even if I
believe that condition to be an error, and I don't want to rule out an
exception for a condition that is not handled locally, even if I
believe that condition not to be an error.

But even if I didn't care about those two, unlike you (I think) I am
not able to identify which conditions I will handle with exceptions
before designing the program structure because I first need to
identify the situations where I need to jump from one point in the
program to some other non-local point. Only after I have decided
(usually reluctantly) that I have that requirement will I consider
various ways to implement it. One of the options is an exception, but
it is only an implementation detail. I still want to communicate
intent, but the intent I want to communicate is "if condition x
arises, the flow of execution needs to jump away from here". If I feel
an exception is the best way of communicating that intent, that's what
I will use.
The question here is not so much whether this decision making process works
for you. It is more about whether recommending this decision making process
to others is wise. It could be that your personal understanding of what
is "cleanest" leads you to use exceptions only rarely. However, I wonder
whether others programmers understanding of what counts as clean is
sufficiently similar and will prevent them from using exceptions
dangerously often.
Well by my approach, exceptions are simply an implementation technique
available when the program structure calls for some spaghetti coding.
My own protection against over-use is that I understand the pitfalls
of jumping around the code and I try and minimise the need to do it.
If someone were following my approach and ended up using exceptions
often, that would not be a problem with my approach, it would be a
problem with their ability to design a program structure that didn't
involve jumping all over the place. Without that ability, even if you
banned exceptions, they would just use some other technique to
implement their spaghetti structure. The only solution I know is the
one you suggest - an increase in wisdom and experience and an
expectation that their approach to the same problem could change
significantly over time.

Gavin Deane

Mar 13 '07 #30
(The thread "Error Handling Idioms" prompted this post)

An attempt at common defintions:

fault: the cause of error.
error: a detected fault.
error handling: planned processing (perhaps via formal mechanisms) that
occurs upon fault detection.
error correction: returning a program (or system) back to an error-free
state.
failure: deviation from specified behavior (such as that which occurs when
an fault is not detected or an error not corrected or aborting).
C++ exception mechanisms, function return codes: 2 ways to facilitate
transfer of control to error handling code.

Note that by the above definitions, it is not always obvious if failure has
occurred. Case A: If a stray electron caused a memory bit to toggle and
caused the program to restart but then behave from there on as expected, I'd
say that is not failure. Case B: OTOH, if the program continually restarts,
I'd call that a failure.

Case A

Fault: stray electron. Error: noted memory corruption. Handling: solves
problem. Failure: Yes. Recovery: Yes.

Case B

Fault: dunno. Error: noted memory corruption. Handling: does not solve
problem. Failure: Yes. Recovery: No.

There are more important things (such as understanding of failure modes) to
worry about than which mechanism one uses to transfer control to an error
handler, IMO. C++ exceptions don't help with detection or correction ('try'
is not detection and 'catch' is not correction), the most important parts.
Also, I think that maybe trying to talk about errors in general rather than
specific errors or categories of errors may be futile.

John

Mar 13 '07 #31
* JohnQ:
(The thread "Error Handling Idioms" prompted this post)

An attempt at common defintions:

fault: the cause of error.
error: a detected fault.
I'd switch those two definitions. ;-)

Anyway, I think the only sensible thing to do is to define what
terminology is used (locally), then use that terminology consistently.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 13 '07 #32

"Alf P. Steinbach" <al***@start.nowrote in message
news:55*************@mid.individual.net...
>* JohnQ:
>(The thread "Error Handling Idioms" prompted this post)

An attempt at common defintions:

fault: the cause of error.
error: a detected fault.

I'd switch those two definitions. ;-)
How exactly? And why the sarcastic wink?
>
Anyway, I think the only sensible thing to do is to define what
terminology is used (locally), then use that terminology consistently.
What to do about this newsgroup locality and enabling discussion across
localities was the goal though.

John
Mar 13 '07 #33
Gavin Deane wrote:
>
I posted a reply yesterday but it's not appeared yet. A delay that
long between posting and seeing the post is unusual through Google
Groups so I'll try again. Apologies for the double post if the first
one eventually appears.
>Since I do not subscribe to the point you question, I might not be
well-posed to answer your call. I will try nonetheless. I know the
following reasons:

a) Code is meant to communicate intent. Since, for better or worse,
exceptions have been popularized by the powers that be as a mechanism for
error handling only, it is wise to follow that rule. Violations are bound
to create misleading expectations in those reading the code.

I absolutely agree with the principle of code communicating intent.
However, for someone to say "exceptions are for error handling only"
is meaningless without a definition of "error".
"Error" is something o[[osite to "state". Error is violation of any
conventions, for example:

inline void zfill(char *const dst, const uint size)
{
if(!size)return;
//it is not error, because some arrays can have zero size

if(!dst)return;
//it is not error, because some arrays can be not allocated

memcpy(dst,0,size);
}

//do not post dst==0
inline void zfill2(char *const dst, const uint size)
{
if(!size)return;
if(!dst)safe_throw<err_zptr>("zfill2: dst");
//it is error, because we have required from client does not post NULL for
dst

memcpy(dst,0,size);
}

In some cases dividing into "error" or "state" is only your convention.

inline uint read(const char *const src)
{
if(!src)safe_throw<err_zptr>("read: src");
//it is error, because what data you will return from NULL?
}

Functions, returning only correct data is one of the source of exceptions,
because we just can not return any useful value while error.

Memory allocation, file opening and other resource management is other
source of exceptions, because we just can not continue if we have no memory
or can not work with file.

No one must use exception as "state switcher", due to low perfomans of
exception handling. Design pattern "state" can be used to implement complex
"state", when concrete methods of concrete interface of class depending from
concrete state.
--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Mar 14 '07 #34
On 14 Mar, 21:02, "Grizlyk" <grizl...@yandex.ruwrote:
GavinDeanewrote:
I absolutely agree with the principle of code communicating intent.
However, for someone to say "exceptions are for error handling only"
is meaningless without a definition of "error".

"Error" is something o[[osite to "state". Error is violation of any
conventions, for example:

inline void zfill(char *const dst, const uint size)
{
if(!size)return;
//it is not error, because some arrays can have zero size

if(!dst)return;
//it is not error, because some arrays can be not allocated

memcpy(dst,0,size);
}
I would not regard those conditions as errors either, assuming (as I
think you do) that the function is intended to handle zero size arrays
and null pointers.
//do not post dst==0
inline void zfill2(char *const dst, const uint size)
{
if(!size)return;
if(!dst)safe_throw<err_zptr>("zfill2: dst");
//it is error, because we have required from client does not post NULL for
dst

memcpy(dst,0,size);
}
That's situation can only arise if there is a bug in the calling code.
I agree that you may want to do something in the function if the
precondition is violated. And you might decide that throwing an
exception is the thing you want to do. But as this situation can only
arise in an incorrect program, your example doesn't tell me anything
about the distinction between "failures" and "errors" in a correct
program.

Gavin

Mar 15 '07 #35
Gavin Deane wrote:
>
I absolutely agree with the principle of code communicating intent.
However, for someone to say "exceptions are for error handling only"
is meaningless without a definition of "error".

"Error" is something opposite to "state". Error is violation of any
conventions, for example:

inline void zfill(char *const dst, const uint size)
{
if(!size)return;
//it is not error, because some arrays can have zero size

if(!dst)return;
//it is not error, because some arrays can be not allocated

memset(dst,0,size);
}

I would not regard those conditions as errors either, assuming (as I
think you do) that the function is intended to handle zero size arrays
and null pointers.
There is no only one answer here. Whithout any additional condition it can
be either error, or not. The best choice to remove the undefined behavior is
strcit definition of the conditions of error. For pointers, the additional
precondition is often "to be non-zero", as the following example
> //do not post dst==0
inline void zfill2(char *const dst, const uint size)
{
if(!size)return;
if(!dst)safe_throw<err_zptr>("zfill2: dst");
// it is error, because we have required from client
// does not post NULL for "dst"

memset(dst,0,size);
}

That's situation can only arise if there is a bug in the calling code.
Yes. It is a bug in caller code, becasue we are assuming programmer can read
comment: "do not post dst==0". Unfortunatelly we can not detect the error at
compile time, so we need exception here, because we can not resolve the
error inside "zfill2" and can not quietly return, because all other correct
parts of code will expect correct zero filled buf.
I agree that you may want to do something in the function if the
precondition is violated. And you might decide that throwing an
exception is the thing you want to do.
We do not want, we are forced to return control into caller, because we do
not know what to do with the error and what part of program executed.

In reliable systems some failed parts of program can be easy stopped with
the help of exception and all other parts will continue to work, in spite of
all of them is sharing common libraries.

I think the best way to do separated reliable parts of program is process or
thread, but some small parts of program can be separated by C++ tools with
try/catch, without making tons of threads.

enum{ parts=10 };
void err_msg(const uint);

typedef void (*foo)();
extern foo part[parts];

extern char state[parts];

int main()
{
try{
memset(state,!0,parts);

for(;;){
for(uint p=0; p<parts; ++p)
{
if(state[p])
try{ part[p](); }
catch(...){ state[p]=0; err_msg(p); }
}}
}
catch(...){err_msg(parts);}
}

By the way, the desire of C++ often to call "terminate" instead of possible
"throw" anything to up level (that can be catched with "catch(...)")
contradicts to reliable system requirements. The known C++ error points are:

- call "terminate" if exception has been thrown in function declared as
"throw()"
- call "terminate" on "double throw".
But as this situation can only
arise in an incorrect program, your example doesn't tell me anything
about the distinction between "failures" and "errors" in a correct
program.
This situation can only arise in a program, developed with independent parts
(in fact in each program). I do not speak about differences between
"failures" and "errors" only about differences between "state" and "errors".
Any "state switching" can be, but must not be resolved by exceptions.
--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Mar 15 '07 #36

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Raymond Hettinger | last post by:
Copying ------- To copy lists and dictionaries, the traditional idioms were l=mylist and d=mydict.copy(). When some of the builtin functions became types, a more consistent approach became...
12
by: Siemel Naran | last post by:
What is a good idiom for handling a lazy object? I see 2 good possibilities. Any more, any comments? Which way do people here use? (1) class Thing { public: Thing(double x, double y) :...
13
by: Thelma Lubkin | last post by:
I use code extensively; I probably overuse it. But I've been using error trapping very sparingly, and now I've been trapped by that. A form that works for me on the system I'm using, apparently...
0
by: JohnQ | last post by:
(The thread "Error Handling Idioms" prompted this post. I meant to post it at the top level, but it got posted as a reply. So here it is again!) An attempt at common defintions: fault: the...
0
by: Lysander | last post by:
Thought I would give something back with a few articles. This article is a bit of code to add error handling. When I have time, I want to write articles on multilingual databases, and Access...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.