Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Error codes vs. exceptions

10 views
Skip to first unread message

mike3

unread,
May 29, 2012, 12:15:00 AM5/29/12
to
Hi.

I've heard about this, and wonder when is it right to use codes, and
when to use exceptions for reporting errors? I've heard various stuff,
such as that exceptions should only be used to indicate "exceptional"
conditions. Yet what does that mean? I've heard that, e.g. a user
inputting invalid input should not be considered "exceptional", but
something like running out of memory should be. Does this mean that if
we have a program, and we have a "parse()" function that parses a
string input by the user, that this function should return an error
code on parse failure, instead of throwing an exception? Yet we'll
probably also come across places where it's good to use an exception,
in the same program! Which means we get into _mixing error codes and
exceptions_. And what's the best way to do that?

Also, how exactly does one go about determining what is and is not
"exceptional"? Two examples were mentioned of things exceptional and
non-exceptional, but what about something else, like say in a game,
where you have a grid representing a game level, and a request for a
tile of the level is made with a coordinate that is off the map (like
a 64x64 map and something requests a tile at (100, 100).). Would it be
OK for the function working on the tile to throw? Or should it give an
"out of range" error code? And as for that mixing: consider, e.g. C++
and probably many other languages: a function has a single definite
return type. Suppose our grid had a function that extracts an
attribute from a cell. What to do when there's an out-of-bounds
request? Throw exception? See, what I've currently been doing, and
it's probably silly, is to use exceptions when our function needs to
return a value, and error codes when it could otherwise return "void".
This doesn't seem like a good idea. But what to do? Make every
function return an error code, using pointers to output variables to
store output, and only use exceptions for a rare few kinds of "system-
related" error? Yet one can hardly deny the niceness of being able to
say "x = f() + <foo>" (inside a "try" block, perhaps) instead of

if(f(&x) != SUCCESS)
{ // handle error }
x += foo;

:)

Note how we can easily get LONG methods full of repeated code with
error codes (repeated error handlers to handle similar errors at
various function calls calling error-code-emitting functions, if one
wants to be more graceful than simply aborting with an error to the
next level up (which complicates what error codes a function can
return, since it can return its own codes in addition to those
returned by the functions below it, and those may have functions below
THEM, and so on...).). And who likes duplicated code? eww. This seems
a disadvantage of error codes.

Or, and this is what I've been thinking of, use exceptions for every
error that the user does not have control over, like invalid input
strings. Would that be OK or excessive use of exceptions? And if we
are to mix error codes and exceptions, does this mean we should have
the lists of codes and exceptions correspond + a translator to
translate between the two?

BGB

unread,
May 29, 2012, 1:10:20 AM5/29/12
to
On 5/28/2012 11:15 PM, mike3 wrote:
> Hi.
>
> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors? I've heard various stuff,
> such as that exceptions should only be used to indicate "exceptional"
> conditions. Yet what does that mean? I've heard that, e.g. a user
> inputting invalid input should not be considered "exceptional", but
> something like running out of memory should be. Does this mean that if
> we have a program, and we have a "parse()" function that parses a
> string input by the user, that this function should return an error
> code on parse failure, instead of throwing an exception? Yet we'll
> probably also come across places where it's good to use an exception,
> in the same program! Which means we get into _mixing error codes and
> exceptions_. And what's the best way to do that?
>

maybe more like this:
use error codes if it can be reasonably done so;
use exceptions if error codes wont really work.

usually, this means returning an error code if the operation can be
handled as a no-op and otherwise the program can continue as normal
(like, "well, that didn't work").

use an exception if this represents a case where normal operation can no
longer reasonably continue (all action past this point is no longer
likely to be in a valid state, such as detecting that some internal
program state is critically wrong).

if it is not clear to use, probably I would opt with error codes.
(usually, when an exception is needed, it is "fairly obvious").
if the function returns a void, use it to return an error code;
if the function returns a pointer, one can potentially return NULL, and
have another operation to fetch the actual error code (stored off in a
variable somewhere);
if the function returns a number, then it is a little harder, sometimes
it can be ">=0 for success, <0 for error", but if the function may
return the full range, it is a bit harder.

one way I have handled it is to have it be similar to the pointer case,
where a certain value (0 or -1), "may" represent an error, and whether
or not it really does is determined by retrieving the error code.

NaN is also a possible error value for floating-point numbers, but is
rarely used this way.

mike3

unread,
May 29, 2012, 1:41:54 AM5/29/12
to
On May 28, 11:10 pm, BGB <cr88...@hotmail.com> wrote:
<snip>
> maybe more like this:
> use error codes if it can be reasonably done so;
> use exceptions if error codes wont really work.
>

So does this mean it is OK to use exceptions for errors in, say, a
constructor, regardless of what the error is?

BGB

unread,
May 29, 2012, 2:34:44 AM5/29/12
to
potentially.

if for some reason the constructor can't actually do its thing, this may
be a reasonable option.

usually, I prefer "graceful" handling whenever possible, meaning that an
exception would only be used in this case if the produced object would
be invalid and there is no "more graceful" way to handle the situation.

there is no solid rules to define this, and it may need to be evaluated
on a case-by-case basis.

Marcel Müller

unread,
May 29, 2012, 3:08:57 AM5/29/12
to
On 29.05.2012 06:15, mike3 wrote:
> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors? I've heard various stuff,
> such as that exceptions should only be used to indicate "exceptional"
> conditions. Yet what does that mean?

Finally it is up to the programmer to take the decision.
But there are some performance aspects as well as some considerations
about exception safe code.

Depending on your language, throwing an exception could be an expensive
task. C++ is yet mostly harmless, but managed languages like Java or
*.NET create an expensive stack trace at the time of the exception
construction or at throw respectively. So it is in general a bad advise
to throw and catch exceptions over and over in loops.

Furthermore exceptions are an unexpected way of changing the execution
flow. While this is intended in most cases there are some pitfalls. Most
code is not fully exception safe. I.e. is shows undefined behavior if
the exception occur at the evaluation of certain (sub-)expressions.
Writing fully exception safe code can be almost as complicated than
writing thread-safe code.
So in fact you should know which of your functions throw exceptions and
which don't. At the end, the advantage of the exceptions, easy code,
might no longer be that large.


> I've heard that, e.g. a user
> inputting invalid input should not be considered "exceptional", but
> something like running out of memory should be.

Well, I dislike general statements like this.

If a wrong user input causes the normal execution flow to be interrupted
at a certain point, a exception might be quite OK. If the execution
continues with the next input box that might be also become red,
exceptions might not hit the nail on the head. You remember, no catch in
a loop (over the controls).


> Also, how exactly does one go about determining what is and is not
> "exceptional"?

You can't determine this. You have to /define/ this.
What causes your program to abandon normal operation (for a while)?


> non-exceptional, but what about something else, like say in a game,
> where you have a grid representing a game level, and a request for a
> tile of the level is made with a coordinate that is off the map (like
> a 64x64 map and something requests a tile at (100, 100).). Would it be
> OK for the function working on the tile to throw?

Does this abort normal program flow?
What is the proper action to be taken next?

> Or should it give an
> "out of range" error code? And as for that mixing: consider, e.g. C++
> and probably many other languages: a function has a single definite
> return type. Suppose our grid had a function that extracts an
> attribute from a cell. What to do when there's an out-of-bounds
> request? Throw exception?

Unless your semantics have some default value which could be used to
continue processing, you won't come around to abort the execution flow
here. But it could be a good advice to check this before you call any
function that will not work properly. I.e. you could turn the array
bounds condition into a precondition which could be checked by an assertion.


> But what to do? Make every
> function return an error code, using pointers to output variables to
> store output, and only use exceptions for a rare few kinds of "system-
> related" error?

Don't do that. Use exception where they make the code easier to read and
easier to understand. And if you run into performance problems, then
look for a work around. But in C++ this is unlikely as long as you do
not abuse them extensively.
A prominent exception to this rule are APIs that can cross language
boundaries. In this case you mostly have no chance. You need error codes.

Another rule of thumb: if throw and catch are close together with
respect to the call stack it is more likely that an error code fit your
needs. If they are well separated, then exceptions might be preferable.


[...]
> Would that be OK or excessive use of exceptions? And if we
> are to mix error codes and exceptions, does this mean we should have
> the lists of codes and exceptions correspond + a translator to
> translate between the two?

Converting an error code into an exception might be a good idea. But the
other way around is most likely not.

And another rule of thumb: the number of exceptions thrown during the
processing of a complete request should be finite. I.e. it must not
scale with the amount of data processed.


Marcel

Dmitry A. Kazakov

unread,
May 29, 2012, 3:37:20 AM5/29/12
to
On Mon, 28 May 2012 21:15:00 -0700 (PDT), mike3 wrote:

> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors?

Return code should be used under no circumstances.

1. return codes cripple design on the callee's side
2. they cuase massive code replication contaminating the source program on
the client side
3. they are unmaintainable (consider adding/removing a code value)
4. they represent a distributed overhead causing less efficient programs on
most of existing architectures

> I've heard various stuff,
> such as that exceptions should only be used to indicate "exceptional"
> conditions. Yet what does that mean?

Exceptional condition is when normal continuation would be impossible.

As an example consider zero divide. It is exceptional because for x /=0
there is no numeric value y such that y * 0 = x.

> I've heard that, e.g. a user
> inputting invalid input should not be considered "exceptional",

That depends on whether continuation is possible. E.g. an improperly
encoded UTF-8 character may be replaced by '?' or raise an exception
causing the caller to sort things out. The choice depends on the
application. The key question is: who is responsible for recovery?

> but
> something like running out of memory should be. Does this mean that if
> we have a program, and we have a "parse()" function that parses a
> string input by the user, that this function should return an error
> code on parse failure, instead of throwing an exception?

When the result would be invalid, parse should raise an exception, e.g.
Syntax_Error with an appropriate message and error location indication.

> Also, how exactly does one go about determining what is and is not
> "exceptional"?

You look at the contract of the thing. e.g. of operation /. If there is no
way to implement the contract, that is exceptional [*]. Another way to put
it: an exception is to propagate from where there is not enough information
to handle it without crippling the design. When you implement file read
operation. At the file end, you don't know what to do. You cannot continue
reading, so you raise End_Error. The caller should have information how to
react. If it does not, it let the exception propagate or raise another
exception, etc.

-----------
* Exception fixes the contract by adding itself as a possible outcome.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

io_x

unread,
May 29, 2012, 4:00:48 AM5/29/12
to

"mike3" <mike...@yahoo.com> ha scritto nel messaggio
news:4f571f71-55ca-4922...@kw17g2000pbb.googlegroups.com...
> Hi.
>

if one use exception that one miss the controll of his program


Jorgen Grahn

unread,
May 29, 2012, 8:24:35 AM5/29/12
to
["Followup-To:" header set to comp.lang.c++.]
On Tue, 2012-05-29, mike3 wrote:
> Hi.
>
> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors?

Are you asking specifically about C++? I will assume "yes", but I get
a bit confused by your crossposting to comp.programming -- what's the
proper use of exceptions varies between languages (and cultures).

> I've heard various stuff,
> such as that exceptions should only be used to indicate "exceptional"
> conditions. Yet what does that mean? I've heard that, e.g. a user
> inputting invalid input should not be considered "exceptional", but
> something like running out of memory should be. Does this mean that if
> we have a program, and we have a "parse()" function that parses a
> string input by the user, that this function should return an error
> code on parse failure, instead of throwing an exception? Yet we'll
> probably also come across places where it's good to use an exception,
> in the same program! Which means we get into _mixing error codes and
> exceptions_. And what's the best way to do that?
>
> Also, how exactly does one go about determining what is and is not
> "exceptional"?

I don't think you should try use the idea of "exceptional" conditions
as a strict rule to apply. IIRC it was something Stroustrup came up with
to explain how he thinks about it, but it's vague; you can debate
what's exceptional or not for years.

Some things are hard to set up general rules for. You have to deal
with them on a case-by-case basis.

> Two examples were mentioned of things exceptional and
> non-exceptional, but what about something else, like say in a game,
> where you have a grid representing a game level, and a request for a
> tile of the level is made with a coordinate that is off the map (like
> a 64x64 map and something requests a tile at (100, 100).). Would it be
> OK for the function working on the tile to throw? Or should it give an
> "out of range" error code?

To me, it has more to do with things like:
- are you going to take steps elsewhere to make out-of-bounds
requests not happen? E.g. document "it's up to the caller
to stay on the map"?
- can it make sense not to handle the error locally?
- would an error code be an unreasonable burden at the calling site,
e.g. you really want to be able to say things like
"get_tile(position).invert();" ?

But it seems you say more or less this below!
As far as I can tell, you think about this pretty much like I do,
except you're still trying to formalize it into some system of rules.
Try not to do that for a while, and see how it feels.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Adam Skutt

unread,
May 29, 2012, 10:16:37 AM5/29/12
to
On May 29, 1:10 am, BGB <cr88...@hotmail.com> wrote:
> On 5/28/2012 11:15 PM, mike3 wrote:
>
> > Hi.
>
> > I've heard about this, and wonder when is it right to use codes, and
> > when to use exceptions for reporting errors? I've heard various stuff,
> > such as that exceptions should only be used to indicate "exceptional"
> > conditions. Yet what does that mean? I've heard that, e.g. a user
> > inputting invalid input should not be considered "exceptional", but
> > something like running out of memory should be. Does this mean that if
> > we have a program, and we have a "parse()" function that parses a
> > string input by the user, that this function should return an error
> > code on parse failure, instead of throwing an exception? Yet we'll
> > probably also come across places where it's good to use an exception,
> > in the same program! Which means we get into _mixing error codes and
> > exceptions_. And what's the best way to do that?
>
> maybe more like this:
> use error codes if it can be reasonably done so;
> use exceptions if error codes wont really work.

Nonsense. A function should only return a value if the caller can use
the return value to further its own computation. It is very rare for
an error code to be useful to the caller, much less all of the codes
returned by a function. Hence, they should be exceptions because
stack unwinding will be needed.

> usually, this means returning an error code if the operation can be
> handled as a no-op and otherwise the program can continue as normal
> (like, "well, that didn't work").

If the error can and should be treated as a no-op then there is no
reason to return anything at all.

> if it is not clear to use, probably I would opt with error codes.
> (usually, when an exception is needed, it is "fairly obvious").

This is precisely backwards. Return values should have clear,
obvious, and unambiguous usage. If you cannot determine what the
caller would do with the return value, then odds are good they will
"pass the buck" and therefore an exception is the right thing.

> > Or, and this is what I've been thinking of, use exceptions for every
> > error that the user does not have control over, like invalid input
> > strings. Would that be OK or excessive use of exceptions? And if we
> > are to mix error codes and exceptions, does this mean we should have
> > the lists of codes and exceptions correspond + a translator to
> > translate between the two?
>
> if the function returns a void, use it to return an error code;

This is nonsense. I assume you meant, "Change the return type to be
an error code" but I honestly have no clue.

> if the function returns a pointer, one can potentially return NULL, and
> have another operation to fetch the actual error code (stored off in a
> variable somewhere);

This requires either extra parameters or a lot of ugly work to create
thread-safe behavior. Which is why error codes are a bad idea. Using
them simply pollutes calling code for no clear benefit, especially
when stack unwinding is necessary (which is the most common case).

Adam

BGB

unread,
May 29, 2012, 10:45:33 AM5/29/12
to
On 5/29/2012 9:16 AM, Adam Skutt wrote:
> On May 29, 1:10 am, BGB<cr88...@hotmail.com> wrote:
>> On 5/28/2012 11:15 PM, mike3 wrote:
>>
>>> Hi.
>>
>>> I've heard about this, and wonder when is it right to use codes, and
>>> when to use exceptions for reporting errors? I've heard various stuff,
>>> such as that exceptions should only be used to indicate "exceptional"
>>> conditions. Yet what does that mean? I've heard that, e.g. a user
>>> inputting invalid input should not be considered "exceptional", but
>>> something like running out of memory should be. Does this mean that if
>>> we have a program, and we have a "parse()" function that parses a
>>> string input by the user, that this function should return an error
>>> code on parse failure, instead of throwing an exception? Yet we'll
>>> probably also come across places where it's good to use an exception,
>>> in the same program! Which means we get into _mixing error codes and
>>> exceptions_. And what's the best way to do that?
>>
>> maybe more like this:
>> use error codes if it can be reasonably done so;
>> use exceptions if error codes wont really work.
>
> Nonsense. A function should only return a value if the caller can use
> the return value to further its own computation. It is very rare for
> an error code to be useful to the caller, much less all of the codes
> returned by a function. Hence, they should be exceptions because
> stack unwinding will be needed.
>

not always, it depends.

if you need to unwind the stack either way, then an exception may make
sense. if not, it is probably not a good answer.


>> usually, this means returning an error code if the operation can be
>> handled as a no-op and otherwise the program can continue as normal
>> (like, "well, that didn't work").
>
> If the error can and should be treated as a no-op then there is no
> reason to return anything at all.
>

usually, the error code will indicate a success/failure in this case.

it is often useful to be able to detect "well, that didn't work",
without needing to be like "on no, stuff has gone terribly wrong".


an example is trying to open a file and searching through a path:
the program may try opening the file along various paths, and see if any
of them work;
in this case, we want to know whether or not the file has been opened
successfully, without needing to catch for every iteration of the loop.


>> if it is not clear to use, probably I would opt with error codes.
>> (usually, when an exception is needed, it is "fairly obvious").
>
> This is precisely backwards. Return values should have clear,
> obvious, and unambiguous usage. If you cannot determine what the
> caller would do with the return value, then odds are good they will
> "pass the buck" and therefore an exception is the right thing.
>

often, if one is using an error code, the operation was probably just
handled as a no-op anyways.

one can use an exception if the situation is sufficiently critical to
where the caller merely carrying on as before would not be a desirable
outcome.

very often, there is no reason to care, and it is better to not burden
the caller with the results, except when they actually care whether or
not the operation succeeded.


>>> Or, and this is what I've been thinking of, use exceptions for every
>>> error that the user does not have control over, like invalid input
>>> strings. Would that be OK or excessive use of exceptions? And if we
>>> are to mix error codes and exceptions, does this mean we should have
>>> the lists of codes and exceptions correspond + a translator to
>>> translate between the two?
>>
>> if the function returns a void, use it to return an error code;
>
> This is nonsense. I assume you meant, "Change the return type to be
> an error code" but I honestly have no clue.
>

fair enough, that could have been written better.

I was responding in context of a prior statement, which basically said
that the OP was using return codes in cases where the function would
otherwise return void.

so, in this case, a person might consider using a return code instead of
a void.


>> if the function returns a pointer, one can potentially return NULL, and
>> have another operation to fetch the actual error code (stored off in a
>> variable somewhere);
>
> This requires either extra parameters or a lot of ugly work to create
> thread-safe behavior. Which is why error codes are a bad idea. Using
> them simply pollutes calling code for no clear benefit, especially
> when stack unwinding is necessary (which is the most common case).
>

I disagree that stack-unwinding is the most common case.
IME, no-op is the most common case, and if the error code is even
checked, it is usually done so to determine a success/failure status (so
that the caller logic can determine whether or not to try a different
option, ...).

as for "in a variable somewhere":
typically, this would be an object field or thread-local variable.

an example would be, say, an object with an "obj->getError()" method or
similar, or a "fooGetError()" function which returns the contents of a
TLS variable, ...


then it is thread-safe...

I didn't say here that it would be a global variable or similar, which
wouldn't be thread-safe.

Nobody

unread,
May 30, 2012, 10:23:07 AM5/30/12
to
On Mon, 28 May 2012 21:15:00 -0700, mike3 wrote:

> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors? I've heard various stuff,
> such as that exceptions should only be used to indicate "exceptional"
> conditions. Yet what does that mean?

It usually means that the condition will rarely occur in practice.

Performance-wise, exceptions are costly if the exception is actually
thrown but free if not thrown, while a status return has a constant
overhead. If the condition rarely occurs, exceptions will work out
cheaper; if the condition is common, returning a status will be cheaper.

But performance is seldom the main issue. If throwing an exception means
that typical code will just wrap the call in a try/catch block, you should
use a status return instead. If typical code will propagate errors up the
call stack, you should probably use an exception.

It's all about code structure. If exceptions make your code cleaner by
reducing the amount of error-handling code, use exceptions. If they just
mean that you replace if/else with try/catch, then use a status return.

BGB

unread,
May 30, 2012, 10:40:20 AM5/30/12
to
On 5/30/2012 9:23 AM, Nobody wrote:
> On Mon, 28 May 2012 21:15:00 -0700, mike3 wrote:
>
>> I've heard about this, and wonder when is it right to use codes, and
>> when to use exceptions for reporting errors? I've heard various stuff,
>> such as that exceptions should only be used to indicate "exceptional"
>> conditions. Yet what does that mean?
>
> It usually means that the condition will rarely occur in practice.
>
> Performance-wise, exceptions are costly if the exception is actually
> thrown but free if not thrown, while a status return has a constant
> overhead. If the condition rarely occurs, exceptions will work out
> cheaper; if the condition is common, returning a status will be cheaper.
>

pretty much.

a status code also has the advantage if the return value is used to
drive logic in the caller, such as knowing when a task has finished,
when a desired item has been found, ...


> But performance is seldom the main issue. If throwing an exception means
> that typical code will just wrap the call in a try/catch block, you should
> use a status return instead. If typical code will propagate errors up the
> call stack, you should probably use an exception.
>

agreed.

exceptions work much better for transferring control across multiple
levels of call frames.

if the handler logic is directly in the caller, then it is less convenient.


similarly, there may be the matter of seriousness:
if the situation is "serious" (as-in, could potentially compromise
correct functioning of the application), then an exception may make more
sense;
if the situation is something which could be reasonably ignored with
little or no consequence, then a status code may make more sense.


> It's all about code structure. If exceptions make your code cleaner by
> reducing the amount of error-handling code, use exceptions. If they just
> mean that you replace if/else with try/catch, then use a status return.
>

yep.

this is often what would happen in many cases, using a try/catch as a
slightly longer, and slower, alternative to an if/else block.

Adam Skutt

unread,
May 30, 2012, 11:04:37 AM5/30/12
to
On May 30, 10:40 am, BGB <cr88...@hotmail.com> wrote:
> On 5/30/2012 9:23 AM, Nobody wrote:
>
> > On Mon, 28 May 2012 21:15:00 -0700, mike3 wrote:
>
> >> I've heard about this, and wonder when is it right to use codes, and
> >> when to use exceptions for reporting errors? I've heard various stuff,
> >> such as that exceptions should only be used to indicate "exceptional"
> >> conditions. Yet what does that mean?
>
> > It usually means that the condition will rarely occur in practice.
>
> > Performance-wise, exceptions are costly if the exception is actually
> > thrown but free if not thrown, while a status return has a constant
> > overhead. If the condition rarely occurs, exceptions will work out
> > cheaper; if the condition is common, returning a status will be cheaper.
>
> pretty much.
>
> a status code also has the advantage if the return value is used to
> drive logic in the caller, such as knowing when a task has finished,
> when a desired item has been found, ...
>

Or you just return the item and avoid the need for status altogether.
Success should be normally be implicit.

> > But performance is seldom the main issue. If throwing an exception means
> > that typical code will just wrap the call in a try/catch block, you should
> > use a status return instead. If typical code will propagate errors up the
> > call stack, you should probably use an exception.
>
> agreed.
>
> exceptions work much better for transferring control across multiple
> levels of call frames.
>
> if the handler logic is directly in the caller, then it is less convenient.

You've said this a whole bunch of times but never once demonstrated
how this is actually true. I can think of a few cases where it's
true, but they're all pretty contrived.

>
> similarly, there may be the matter of seriousness:
> if the situation is "serious" (as-in, could potentially compromise
> correct functioning of the application), then an exception may make more
> sense;
> if the situation is something which could be reasonably ignored with
> little or no consequence, then a status code may make more sense.
>

As I've explained to you before, it's normally impossible for the
function issuing the error to tell the difference between these two
situations. Again, you've never once demonstrated how to apply this
reasoning to writing correct, usable code.

Adam

BGB

unread,
May 30, 2012, 1:01:04 PM5/30/12
to
On 5/30/2012 10:04 AM, Adam Skutt wrote:
> On May 30, 10:40 am, BGB<cr88...@hotmail.com> wrote:
>> On 5/30/2012 9:23 AM, Nobody wrote:
>>
>>> On Mon, 28 May 2012 21:15:00 -0700, mike3 wrote:
>>
>>>> I've heard about this, and wonder when is it right to use codes, and
>>>> when to use exceptions for reporting errors? I've heard various stuff,
>>>> such as that exceptions should only be used to indicate "exceptional"
>>>> conditions. Yet what does that mean?
>>
>>> It usually means that the condition will rarely occur in practice.
>>
>>> Performance-wise, exceptions are costly if the exception is actually
>>> thrown but free if not thrown, while a status return has a constant
>>> overhead. If the condition rarely occurs, exceptions will work out
>>> cheaper; if the condition is common, returning a status will be cheaper.
>>
>> pretty much.
>>
>> a status code also has the advantage if the return value is used to
>> drive logic in the caller, such as knowing when a task has finished,
>> when a desired item has been found, ...
>>
>
> Or you just return the item and avoid the need for status altogether.
> Success should be normally be implicit.
>

only if one knows that the function will almost always succeed (IOW:
succeeding is part of its "definition of operation").

if it may also fail as part of its normal/expected operation, then it no
longer is so clear cut.


succeeding/failing need not be the same as an error/non-error condition,
but may be due to other factors (such as an item not already being in a
list or hash-table and needing to be created, ...).

not all status codes indicate errors as well, and there may actually be
successful status codes as well (traditionally these are distinguished
by sign, where <0 means failure, and >=0 means success).


>>> But performance is seldom the main issue. If throwing an exception means
>>> that typical code will just wrap the call in a try/catch block, you should
>>> use a status return instead. If typical code will propagate errors up the
>>> call stack, you should probably use an exception.
>>
>> agreed.
>>
>> exceptions work much better for transferring control across multiple
>> levels of call frames.
>>
>> if the handler logic is directly in the caller, then it is less convenient.
>
> You've said this a whole bunch of times but never once demonstrated
> how this is actually true. I can think of a few cases where it's
> true, but they're all pretty contrived.
>

I make heavy use of code driven by "predicate functions" (functions or
methods which return a boolean value to indicate status), which are
arguably the same sort of thing as what you are arguing against.

it is all a fairly pointless and nit-picky argument at this point.



>>
>> similarly, there may be the matter of seriousness:
>> if the situation is "serious" (as-in, could potentially compromise
>> correct functioning of the application), then an exception may make more
>> sense;
>> if the situation is something which could be reasonably ignored with
>> little or no consequence, then a status code may make more sense.
>>
>
> As I've explained to you before, it's normally impossible for the
> function issuing the error to tell the difference between these two
> situations. Again, you've never once demonstrated how to apply this
> reasoning to writing correct, usable code.
>

usually a person writing an application will know what the code in the
thing is going to be doing, as well as the consequences of a given
operation succeeding or failing.

usually it is also "fairly obvious" from what the function is going to
be doing as well.


now, I am not opposing using exceptions here, by any means, as there are
many cases where they do make sense (namely, cases where the situation
*actually is* unexpected or abnormal).

for example:
running out of memory, or detecting a problem with the heap, is
something a bit more worthy of an exception.

Jeff Flinn

unread,
May 30, 2012, 2:18:16 PM5/30/12
to
On 5/29/2012 12:15 AM, mike3 wrote:
> Hi.
>
> I've heard about this, and wonder when is it right to use codes, and
> when to use exceptions for reporting errors?...

The best advice I've seen is from
http://www.boost.org/community/error_handling.html

"The simple answer is: ``whenever the semantic and performance
characteristics of exceptions are appropriate.''

An oft-cited guideline is to ask yourself the question ``is this an
exceptional (or unexpected) situation?'' This guideline has an
attractive ring to it, but is usually a mistake. The problem is that one
person's ``exceptional'' is another's ``expected'': when you really look
at the terms carefully, the distinction evaporates and you're left with
no guideline. After all, if you check for an error condition, then in
some sense you expect it to happen, or the check is wasted code.

A more appropriate question to ask is: ``do we want stack unwinding
here?'' Because actually handling an exception is likely to be
significantly slower than executing mainline code, you should also ask:
``Can I afford stack unwinding here?'' For example, a desktop
application performing a long computation might periodically check to
see whether the user had pressed a cancel button. Throwing an exception
could allow the operation to be cancelled gracefully. On the other hand,
it would probably be inappropriate to throw and handle exceptions in the
inner loop of this computation because that could have a significant
performance impact. The guideline mentioned above has a grain of truth
in it: in time critical code, throwing an exception should be the
exception, not the rule."

Jeff

Patricia Shanahan

unread,
May 30, 2012, 4:00:25 PM5/30/12
to
On 5/30/2012 11:18 AM, Jeff Flinn wrote:
...
> A more appropriate question to ask is: ``do we want stack unwinding
> here?'' Because actually handling an exception is likely to be
> significantly slower than executing mainline code, you should also ask:
> ``Can I afford stack unwinding here?'' For example, a desktop
> application performing a long computation might periodically check to
> see whether the user had pressed a cancel button. Throwing an exception
> could allow the operation to be cancelled gracefully. On the other hand,
> it would probably be inappropriate to throw and handle exceptions in the
> inner loop of this computation because that could have a significant
> performance impact. The guideline mentioned above has a grain of truth
> in it: in time critical code, throwing an exception should be the
> exception, not the rule."
...

*Any* style rule or pattern has a potential for being overridden by
important performance concerns. That does not mean we should not ask
"What is good style?".

I usually prefer exceptions:

1. Exceptions leave the function result available for the natural result.

2. In many languages, exceptions encode more information more directly
than is possible with status codes.

3. Exception processing can be grouped at the end of a block of code,
with the non-exception flow left clear. Status codes tend to result in
interleaving exception handling throughout the main line flow.

Patricia

Pavel

unread,
May 30, 2012, 10:44:56 PM5/30/12
to
I know you have already received lots of advice; but I think they omit an
important factor, namely whether you are writing a library. In my experience, I
found it quite annoying when the API of a library I use can throw. Catching all
possible exceptions after every call is even more disrupting than processing
return codes and letting them through often creates a mess with multiple error
processing policies coming from different libraries or from my application and
library or libraries it uses.

In addition, a library writer does not always know the performance requirements
of the future client code, especially if it is going to be a successful library
and calling throwing function incurs overhead.

Using "golden rule", I refrain from exposing exceptions in APIs to my libraries
and strive to make all top-level functions nothrow regardless of whether or not
I use them inside the library implementation.

HTH,
-Pavel



Nobody

unread,
May 31, 2012, 12:04:36 AM5/31/12
to
On Wed, 30 May 2012 22:44:56 -0400, Pavel wrote:

> I know you have already received lots of advice; but I think they omit an
> important factor, namely whether you are writing a library. In my
> experience, I found it quite annoying when the API of a library I use can
> throw. Catching all possible exceptions after every call is even more
> disrupting than processing return codes and letting them through often
> creates a mess with multiple error processing policies coming from
> different libraries or from my application and library or libraries it
> uses.

That's a non-issue for exceptions which should never need to be thrown
in the first place, e.g. an invalid argument value. If you don't want to
have to catch such exceptions, don't cause them to be thrown.

Even where it is an issue, any API design involves trade-offs. Having
every function return a status indication may be more efficient for code
which always handles failures directly in the caller. OTOH, it imposes a
significant burden on code which would otherwise just allow an exception
to propagate up to a higher level.

It's impossible to provide a hard-and-fast definition of which conditions
are "exceptional", particularly for a library. OTOH, it's equally
impossible to provide a hard-and-fast rule regarding the side on which to
err.

Treating any condition which might conceivably be caught in the immediate
caller as non-exceptional is likely to result in a rather inconvenient API
for the majority of code. I mean, the STL *could* have a given every
container type a "bad bit" (in the same vein as iostream) to indicate
allocation failure, but I'm rather glad it didn't.

Adam Skutt

unread,
May 31, 2012, 12:25:47 AM5/31/12
to
On May 30, 2:18 pm, Jeff Flinn <TriumphSprint2...@hotmail.com> wrote:
> On 5/29/2012 12:15 AM, mike3 wrote:
>
> > Hi.
>
> > I've heard about this, and wonder when is it right to use codes, and
> > when to use exceptions for reporting errors?...
>
> The best advice I've seen is fromhttp://www.boost.org/community/error_handling.html
>
> "The simple answer is: ``whenever the semantic and performance
> characteristics of exceptions are appropriate.''
>
>
> A more appropriate question to ask is: ``do we want stack unwinding
> here?'' Because actually handling an exception is likely to be
> significantly slower than executing mainline code, you should also ask:
> ``Can I afford stack unwinding here?'' For example, a desktop
> application performing a long computation might periodically check to
> see whether the user had pressed a cancel button. Throwing an exception
> could allow the operation to be cancelled gracefully. On the other hand,
> it would probably be inappropriate to throw and handle exceptions in the
> inner loop of this computation because that could have a significant
> performance impact. The guideline mentioned above has a grain of truth
> in it: in time critical code, throwing an exception should be the
> exception, not the rule."

Except that your guidance doesn't apply here. Modern C++ runtimes
incur no execution overhead for exception handling unless an exception
is actually thrown. Since the goal is to terminate the loop entirely,
an exception would be perfectly reasonable in principal. Where it
might unreasonable is if the exception were to be caught and then
computation resumed. However, it's pointless to assume throwing an
exception will be a problem without measuring.

Adam

mike3

unread,
May 31, 2012, 4:52:40 PM5/31/12
to
On May 29, 1:08 am, Marcel Müller <news.5.ma...@spamgourmet.com>
wrote:
<snip>
> > Would that be OK or excessive use of exceptions? And if we
> > are to mix error codes and exceptions, does this mean we should have
> > the lists of codes and exceptions correspond + a translator to
> > translate between the two?
>
> Converting an error code into an exception might be a good idea. But the
> other way around is most likely not.
>
> And another rule of thumb: the number of exceptions thrown during the
> processing of a complete request should be finite. I.e. it must not
> scale with the amount of data processed.
>
> Marcel

So does this mean we should have an exception class defined for every
error code, so we can do that "conversion"?

Ian Collins

unread,
May 31, 2012, 5:08:21 PM5/31/12
to
That really depends what you intend to do when you catch one. I tend to
use an exception type for a family of error codes and include the actual
code in there. Most of my simple applications just catch the base
exception (std::runtime_error), send the result of what() to cerr and exit.

If the application can recover from a specific type of exception, I'll
catch those a perform whatever recovery or reporting is required.

--
Ian Collins
Message has been deleted

mike3

unread,
Jun 1, 2012, 1:32:32 AM6/1/12
to
On May 31, 3:08 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 06/ 1/12 08:52 AM, mike3 wrote:
<snip>
> > So does this mean we should have an exception class defined for every
> > error code, so we can do that "conversion"?
>
> That really depends what you intend to do when you catch one. I tend to
> use an exception type for a family of error codes and include the actual
> code in there. Most of my simple applications just catch the base
> exception (std::runtime_error), send the result of what() to cerr and exit.
>
> If the application can recover from a specific type of exception, I'll
> catch those a perform whatever recovery or reporting is required.
>

I.e. don't make exception classes for every error code but make them
for
a family of error codes?

Pavel

unread,
Jun 1, 2012, 9:44:08 PM6/1/12
to
Stefan Ram wrote:
> Pavel<pauldont...@removeyourself.dontspam.yahoo> writes:
>> I know you have already received lots of advice; but I think they omit an
>> important factor, namely whether you are writing a library. In my experience, I
>> found it quite annoying when the API of a library I use can throw.
>
> And that leads to an answer to the OP's question: When in Rome do as the
> Romans do!
That's what I always profess. With exceptions, however, it might be unclear
where's Rome and where's Athens. Just a quick example off the top of my head:

When using STL, use std::exception hierarchy.
When using WFC, use System::Exception.
When using Qt, use return codes, but for passing errors between threads, inherit
your exceptions from QtConcurrent::Exception

I believe WFC, Qt and many recent implementations of STL all are high-quality,
mostly well-designed library; the first two are also immense in coverage. More
often than not it's not an option not to use them (or other libraries pertinent
to your application's domain).

Where is Rome?

When you write your own library that will most often used with WFC, often with
Qt and always with some STL -- how shall you expose your errors?

When you write your own library that uses WFC -- and of course STL how shall you
expose your library's errors and where should you catch std::exception (which
are fortunately rare) and guys from System::Exception hierarchy (which are much
more often)?

When you write an application that uses all 3 or even only two libraries -- what
errors shall you use inside your application? Many large application require
particular processing of particular error conditions (error logs, alarms,
interfaces to enterprise event handling systems, what's not) -- are you going to
proliferate these exceptions? Usually, you don't. The benefits of uniform error
processing aside, why will you want to make more parts of your code dependent on
the libraries only because their exceptions may penetrate them and the errors
are need to be processed there? What if you need to replace such a big library
with another monster (e.g. to port your library). How are you going to tear
these dependencies out?

If you are a responsible designer, you will provide your own error processing
layer and you will have to meticulously catch and either process or crack and
refactor all errors before letting them further in a thin layer wrapping the
library calls your application uses. The code to capture error codes is simpler,
shorter and faster than that needed to capture exceptions.

As a free bonus, you (or your user if you are the library writer) can always
make a choice between writing throw and nothrow functions at no coding cost.

On top of this, following the code that only calls nothrow methods is much
easier which increases the programmer's productivity. You know, programmers of
successful real-life applications and libraries (which is equivalent to saying
"applications and libraries of significant size") have to spend more time on
reading and understanding code of others than on writing their own code.

Do your math yourself. I did mine many years ago and have never had a reason to
be sorry of this my application of golden rule.

> When in a programming language do as the standard library does!
> Look at the standard library and observe what means it uses to signal
> the status of attempts, and then use these means!
>
> In C++, »standard library« here does not mean that part inherited from
> C, but more that part written specifically for C++.
>

-Pavel

Alf P. Steinbach

unread,
Jun 2, 2012, 2:39:14 AM6/2/12
to
On 29.05.2012 06:15, mike3 wrote:
> Hi.
>
> I've heard about this [Error codes vs. exceptions], and wonder when is it
> right to use codes, and when to use exceptions for reporting errors?

Use whatever's more clear and practical in any given case.

And note that "codes" include the case of zero information about what
failed, where there's only one success indicating code (like boolean
"true") and one failure indicating code (like boolean "false")...

Also note that there are many other techniques for handling failures
that occur in a function f:

* let f return a possibly empty result
e.g. check out Barton/Nackman "Fallible" and Boost "optional"


* let f call an error handling routine, that's possibly configurable
a great many libraries do this

* let f terminate the program
a bit harsh, but e.g. a JPEG library used by ImageMagick did this

* let f involve the user and try to fix the problem
this was used in Windows for missing removable media, missing
DLLs and so on, with a box that like DOS did earlier said "abort,
ignore, retry" (or the like)

* let f simply have undefined behavior
may sound pretty stupid but is used by e.g. the C++ standard library
for functions where failures only are caused by failed preconditions

Regardless, you have the option of letting f log the incident, or not.

But generally, e.g. when I'm going to call a C library function or
Windows API function that (as they typically do) has some ad hoc fault
indication + some error code scheme, then I usually wrap it in a
function or expression that throws a C++ exception. That's generally
more convenient even for local handling of the failure. And one main
reason is that it encapsulates and gets rid of all the myriad ad hoc
schemes for checking whether the function failed and for responding to
it -- it's a standardization and simplification.

As an example,

<code>
// `errno` may be an expression macro, so it cannot (portably) be
qualified with "::".
int stdErrno() { return errno; }
void clearStdErrno() { errno = 0; }

bool hopefully( bool const condition ) { return condition; }
bool throwX( string const& s ) { throw runtime_error( s ); }


long longFrom(
char const spec[],
int const radix = 0,
bool const acceptTrailingChars = false
)
{
char* pEndOfScan = 0; // The unsafe type is required by `strtol`.

clearStdErrno();
long const result = strtol( spec, &pEndOfScan, radix );
string const failureDescription = 0?string()
: pEndOfScan == spec?
"longFrom failed: the number spec was not accepted by
strtol()."
: stdErrno() == ERANGE?
"longFrom failed: the specified number value is too large
for strtol()."
: stdErrno() != 0?
S() << "longFrom failed: strtol() failed, errno = " <<
stdErrno() << "."
: *pEndOfScan != '\0' && !acceptTrailingChars?
"longFrom failed: extraneous character(s) after valid
number spec."
:
"";
hopefully( failureDescription.length() == 0 )
|| throwX( failureDescription );
return result;
}
</code>


As shown by the various exception messages there are (at least) 4 ways
that "strtol" can fail.

I would speculate that in many programs using the "strtol" function
directly, not all failure paths are checked -- but the wrapper
replaces the sequence of four ad hoc checks with simple standard C++
exception handling. Of course, with a C++11 conforming compiler there's
little need to call "strtol" because in C++11 iostreams do that for you
(C++03 instead used the "scanf" family, with possible Undefined
Behavior). But I think it illustrates the case for wrapping in C++.

So, C = preference for codes, error handlers functions etc., and C++ =
preference for exceptions. But in some cases, as with e.g. calls across
binary module boundaries, you can't assume C++ exception support. Then
you have to design for the code to be callable as C, i.e. no exceptions.

All that said, I'm primarily responding because I'm really curious about
where this great need for MECHANICAL RULES comes from?

If programming could be reduced to mechanical rules, if that was a good
idea, then, u know, it could be automated, and then you would not have
this problem of finding the rules because you wouldn't be programming:
it would be done by machine... So, instead of seeking mechanical rules
to be applied mindlessly, I suggest seeking up concrete EXAMPLES of
failure handling. Then apply INTELLIGENCE and understanding of concrete
situations that you face, and just strive to Keep Things Simple. ;-)


Cheers & hth.,

- Alf

BGB

unread,
Jun 2, 2012, 5:31:26 PM6/2/12
to
On 6/2/2012 1:39 AM, Alf P. Steinbach wrote:
> On 29.05.2012 06:15, mike3 wrote:
>> Hi.
>>
>> I've heard about this [Error codes vs. exceptions], and wonder when is it
>> right to use codes, and when to use exceptions for reporting errors?
>
> Use whatever's more clear and practical in any given case.
>

generally agreed.


> And note that "codes" include the case of zero information about what
> failed, where there's only one success indicating code (like boolean
> "true") and one failure indicating code (like boolean "false")...
>
> Also note that there are many other techniques for handling failures
> that occur in a function f:
>
> * let f return a possibly empty result
> e.g. check out Barton/Nackman "Fallible" and Boost "optional"
>

possibly.


>
> * let f call an error handling routine, that's possibly configurable
> a great many libraries do this
>

seems good.


> * let f terminate the program
> a bit harsh, but e.g. a JPEG library used by ImageMagick did this
>

I personally consider this to be an unreasonable strategy in the general
case, since then a "reasonable" or even "trivial" issue may cause the
application to die, possibly without any way to recover short of the
application not using the library in the first place.


I have ended up dropping libraries in the past for pulling this sort of
thing (well, among other things).

like:
call library to load something from a file;
file fails to open;
library calls "abort()".

this is along with the annoyance of libraries which can only work with
files, but the data in question (in the application) is held in buffers
or similar.



> * let f involve the user and try to fix the problem
> this was used in Windows for missing removable media, missing
> DLLs and so on, with a box that like DOS did earlier said "abort,
> ignore, retry" (or the like)
>

in most cases, this probably shouldn't be done in library code (but
should probably be left up to the application).

it was an extra annoyance a while back trying to figure out how to go
about making Windows not throw up a dialog box whenever a
"LoadLibrary()" call failed to work (Windows just assumed that a
"LoadLibrary()" call failing was a serious problem, rather than, say,
this call being used to check for an optional component).

luckily, there was an option to disable said dialog.



> * let f simply have undefined behavior
> may sound pretty stupid but is used by e.g. the C++ standard library
> for functions where failures only are caused by failed preconditions
>

possibly, in this case.

I generally prefer code which doesn't just randomly blow up though, if
possible (usually, about the only real cases it is a good idea to skip
over basic "sanity checks" is in cases of "potentially performance
critical" code).


fairly common in my case is that, if the code for whatever reason can't
do what is requested, it will function as a no-op and indicate that it
has failed (and sometimes log the error if likely relevant).

in many cases, "assert" or similar can also be useful (in the case of
"clearly wrong behavior which should never occur during operation", for
example a required parameter being NULL, ...).

for example, if a required parameter is NULL or argument values are
invalid, very likely the caller has done something wrong, and it is
likely a good idea to trap into the debugger.

this isn't IMO a good strategy for "general issues" though, but more for
cases where "the caller has clearly done something wrong" or similar.


> Regardless, you have the option of letting f log the incident, or not.
>

I actually do a fair amount of logging.

typically my apps will spit out a fair amount of information to logs as
part of their start-up process, and typically this will consist largely
of debugging-related messages.

this is fairly useful as, sadly, not everything can be easily tracked
down in a debugger (very often the case with bugs which result from
interactions between components, where often much of the effort may come
down to trying to track down just where exactly the bug actually is or
the state of the system in cases where it manifests).


> But generally, e.g. when I'm going to call a C library function or
> Windows API function that (as they typically do) has some ad hoc fault
> indication + some error code scheme, then I usually wrap it in a
> function or expression that throws a C++ exception. That's generally
> more convenient even for local handling of the failure. And one main
> reason is that it encapsulates and gets rid of all the myriad ad hoc
> schemes for checking whether the function failed and for responding to
> it -- it's a standardization and simplification.

yep, seems reasonable as such.


decided mostly to leave out descriptions of some of the hassles of
trying to use exception handling in C code via hand-rolled mechanisms
(it can be done, but isn't very pretty), or dealing with cross-language
error-handling (extra fun when the project is split between 3 or more
languages).


< snip, strtol example >

>
> As shown by the various exception messages there are (at least) 4 ways
> that "strtol" can fail.
>
> I would speculate that in many programs using the "strtol" function
> directly, not all failure paths are checked -- but the wrapper replaces
> the sequence of four ad hoc checks with simple standard C++ exception
> handling. Of course, with a C++11 conforming compiler there's little
> need to call "strtol" because in C++11 iostreams do that for you (C++03
> instead used the "scanf" family, with possible Undefined Behavior). But
> I think it illustrates the case for wrapping in C++.
>

fair enough.


> So, C = preference for codes, error handlers functions etc., and C++ =
> preference for exceptions. But in some cases, as with e.g. calls across
> binary module boundaries, you can't assume C++ exception support. Then
> you have to design for the code to be callable as C, i.e. no exceptions.
>

yep.

it is better not to require a particular language for a library interface.

sometimes optional wrapper interfaces may make sense though, such as
wrapper classes or overloaded operators, ...


> All that said, I'm primarily responding because I'm really curious about
> where this great need for MECHANICAL RULES comes from?
>
> If programming could be reduced to mechanical rules, if that was a good
> idea, then, u know, it could be automated, and then you would not have
> this problem of finding the rules because you wouldn't be programming:
> it would be done by machine... So, instead of seeking mechanical rules
> to be applied mindlessly, I suggest seeking up concrete EXAMPLES of
> failure handling. Then apply INTELLIGENCE and understanding of concrete
> situations that you face, and just strive to Keep Things Simple. ;-)
>

I actually have little idea where it comes from, but I have seen lots of
this in a number of language groups, namely people who believe that
"language X must be used this particular way", following certain little
rules (often trivial, sometimes arcane), and also that they represent
"authority" on "what everyone using the language does and believes".


sometimes, there are good "rules of thumb", but ultimately it comes down
to whether or not the rule will be beneficial in a given situation,
rather than it being something which must always be followed (even in
situations where it doesn't make sense or would do more harm than good).

although, sometimes there are edge cases, for example, "goto":
there is a rule to never use "goto";
then again, there are some potential edge cases where it could be
useful, and it seems disagreeable to ban a feature outright;
however, for code that is not already a mess, it is very rare to
actually have much need to use a "goto" to begin with (so, it seems more
like it is a symptom of spaghetti code, rather than the cause of said
spaghetti code).


many other cases appear to be similar, with people more often focusing
more on the symptoms of a problem, rather than on the cause of the
problem. ( they see the symptoms and the cause as one and the same? )


or such...

mike3

unread,
Jun 2, 2012, 6:49:12 PM6/2/12
to
On Jun 2, 12:39 am, "Alf P. Steinbach" <alf.p.steinbach
+use...@gmail.com> wrote:
> On 29.05.2012 06:15, mike3 wrote:
<snip>
> All that said, I'm primarily responding because I'm really curious about
> where this great need for MECHANICAL RULES comes from?
>
> If programming could be reduced to mechanical rules, if that was a good
> idea, then, u know, it could be automated, and then you would not have
> this problem of finding the rules because you wouldn't be programming:
> it would be done by machine... So, instead of seeking mechanical rules
> to be applied mindlessly, I suggest seeking up concrete EXAMPLES of
> failure handling. Then apply INTELLIGENCE and understanding of concrete
> situations that you face, and just strive to Keep Things Simple. ;-)
>

So where could I get examples of _well-written_, _well-designed_,
_smell-free_ error handling in a _non-trivial_ program?

And also, perhaps I'm not necessarily so interested in rigid rules as
to
understand better how to make "good" code.

A big problem is that I seem to find a lot of conflicting information.
Some say use exceptions, others say use codes, others say use
exceptions only when "exceptional", otherwise presumably use codes.
But codes have a number of problems of their own (see the thread
on comp.lang.c where I deal with C where there are no exceptions
and only codes). Which makes me want to use exceptions. And
indeed, some say that -- use exceptions. But then I get this thing
in my head saying "but maybe those people who say it should only
be used in 'exceptional' circumstances have a good point". And
then I'm once again confused. And then what "exceptional" means
is itself, apparently dependent on the speaker.

Would I be right to think the best thing to do here is just pick an
approach and see where it goes, don't bother worrying who's more
"right"? Is this just one of those things that simply does not *have*
a pat, objective answer, and so you have to do some picking and
choosing and seeing what happens?

And then I look at examples with other programs, and I see the
practices someone says "no" to being used! "NO" globals, there's
a global! And sometimes it's not even just one but a whole lot!
"NO" GOTOs, and oh my gosh what is that?! A GOTO!!!!! Keep
methods "under 20 lines", and then I see a lot of huge methods.
And it doesn't help when the tone I hear from the people and places
saying "no" is one of near-finality, like these things should only be
used in RARE circumstances.

Ian Collins

unread,
Jun 2, 2012, 7:17:06 PM6/2/12
to
On 06/ 3/12 10:49 AM, mike3 wrote:
> On Jun 2, 12:39 am, "Alf P. Steinbach"<alf.p.steinbach
> +use...@gmail.com> wrote:
>> On 29.05.2012 06:15, mike3 wrote:
> <snip>
>> All that said, I'm primarily responding because I'm really curious about
>> where this great need for MECHANICAL RULES comes from?
>>
>> If programming could be reduced to mechanical rules, if that was a good
>> idea, then, u know, it could be automated, and then you would not have
>> this problem of finding the rules because you wouldn't be programming:
>> it would be done by machine... So, instead of seeking mechanical rules
>> to be applied mindlessly, I suggest seeking up concrete EXAMPLES of
>> failure handling. Then apply INTELLIGENCE and understanding of concrete
>> situations that you face, and just strive to Keep Things Simple. ;-)
>>
>
> So where could I get examples of _well-written_, _well-designed_,
> _smell-free_ error handling in a _non-trivial_ program?
>
> And also, perhaps I'm not necessarily so interested in rigid rules as
> to
> understand better how to make "good" code.
>
> A big problem is that I seem to find a lot of conflicting information.
> Some say use exceptions, others say use codes, others say use
> exceptions only when "exceptional", otherwise presumably use codes.

I don't think anyone advocates mixing styles. Pick one or the other.

> But codes have a number of problems of their own (see the thread
> on comp.lang.c where I deal with C where there are no exceptions
> and only codes).

Which is why most modern languages have exceptions.

> Which makes me want to use exceptions. And
> indeed, some say that -- use exceptions. But then I get this thing
> in my head saying "but maybe those people who say it should only
> be used in 'exceptional' circumstances have a good point". And
> then I'm once again confused. And then what "exceptional" means
> is itself, apparently dependent on the speaker.

If you go down the exceptions route, your functions will either have a
void return or return a value. Your functions will do what they are
contracted to do and throw an exception if they are unable to meet their
obligations. That may involve the option of spitting some operations
into two calls (say does item X exist and get item X). The client code
can happily call the functions and move on. The error handling is not
mixed in with the programme logic, it is collected together in exception
handler(s). If that style suits you, follow it.

If you prefer to mix error handling with programme logic, use error
codes and make sure to check them!

> Would I be right to think the best thing to do here is just pick an
> approach and see where it goes, don't bother worrying who's more
> "right"? Is this just one of those things that simply does not *have*
> a pat, objective answer, and so you have to do some picking and
> choosing and seeing what happens?

Yes, assuming a green field project. Otherwise use the "when in Rome"
approach.

> And then I look at examples with other programs, and I see the
> practices someone says "no" to being used! "NO" globals, there's
> a global! And sometimes it's not even just one but a whole lot!
> "NO" GOTOs, and oh my gosh what is that?! A GOTO!!!!! Keep
> methods "under 20 lines", and then I see a lot of huge methods.
> And it doesn't help when the tone I hear from the people and places
> saying "no" is one of near-finality, like these things should only be
> used in RARE circumstances.

Creating rules and ignoring them is a clear sign of a broken process.
If anyone were to find a goto in my code, I would be obliged to buy them
a very large quantity of beer.

--
Ian Collins

Rui Maciel

unread,
Jun 3, 2012, 11:38:42 AM6/3/12
to
mike3 wrote:

> A big problem is that I seem to find a lot of conflicting information.
> Some say use exceptions, others say use codes, others say use
> exceptions only when "exceptional", otherwise presumably use codes.
> But codes have a number of problems of their own (see the thread
> on comp.lang.c where I deal with C where there are no exceptions
> and only codes). Which makes me want to use exceptions. And
> indeed, some say that -- use exceptions. But then I get this thing
> in my head saying "but maybe those people who say it should only
> be used in 'exceptional' circumstances have a good point". And
> then I'm once again confused. And then what "exceptional" means
> is itself, apparently dependent on the speaker.

In some cases, both exceptions and error codes are adequate solutions.
Therefore, it isn't necessarily wrong or a bad idea to use either one in
those cases, and the decision to pick one tends to be a design decision.
Hence the apparently conflicting suggestions.

Personally, I see exceptions as a way to handle errors in a sequence point
other than the one immediately after where the errors are thrown. As a
downside, when you throw an exception you explicitly declare that you don't
know or even care which sequence point will be executed next. You trust
that the exception catching code does the right thing, and that the
program's execution will resume in a safe, innocuous sequence point.


> Would I be right to think the best thing to do here is just pick an
> approach and see where it goes, don't bother worrying who's more
> "right"? Is this just one of those things that simply does not have
> a pat, objective answer, and so you have to do some picking and
> choosing and seeing what happens?

That sounds like a recipe for a mild disaster. After all, if you use a tool
without even thinking if it is the right one for your job then how do you
even know it is a good idea to use it?

A decent rule of thumb that helps see which solution is better suited is as
follows:
- if you are dealing with exceptional circumstances which can be omitted
from the control flow of your code without jeopardizing clarity or
readability (i.e., memory allocation errors, sanity checks failing in an
unexpected way, network connections breaking up, etc...) then exceptions may
be a good way to go.
- if, instead, you are dealing with expectable errors which directly
influence the control flow of your code to the point you can't express an
algorithm without explicitly covering them then returning error codes may be
a good way to go.

Other than this, it's a matter of understanding how exceptions and error
codes work, particularly their downsides, and make a design decision on
which one to pick to handle a particular error.


Rui Maciel

Pavel

unread,
Jun 3, 2012, 8:26:35 PM6/3/12
to
Thanks for the great real-world example, Alf!

I am largely agree to your post but, as I often use strto.. family of functions,
I have few comments:

>
> As shown by the various exception messages there are (at least) 4 ways that
> "strtol" can fail.
Please note that one of them requires your application-specific flag,
`acceptTrailingChars' to be detected. It is an often case that an application
requires this flag (sometimes, the result of strtol shall be in a range (even if
as broad as range of int because there is no equivalent strtoi standard
function). This supports my earlier point that often some application-level
tweaking has to be done directly after calling a 3rd-party library function. In
your case if strtol were a C++ function and threw exception where it now sets
errno, you would still need to write some error-processing code right after
calling the function for this condition.

>
> I would speculate that in many programs using the "strtol" function directly,
> not all failure paths are checked -- but the wrapper replaces the sequence of
> four ad hoc checks with simple standard C++ exception handling.Of course, with
> a C++11 conforming compiler there's little need to call "strtol" because in
> C++11 iostreams do that for you
As a frequent user of strtoXxx and streams I tend to disagree. To even
approximately match the performance of my current code, using streams would make
me implement my own streambuf over given fixed buffer (which I really do not
need as I am fine with the more mundane approach of parsing from specific
position in my directly-manipulated read buffer (which is essentially a RAII
holder over character buffer, that is a much simpler class than streambuf)).

I thought of using strings as buffers and parsing istringstream but rejected the
idea. The direct manipulations with the contents of std::string-underlying
stringbuffer are UB and using string modifiers would trigger contents copy on
COW strings (for non-COW strings I would pay for the contents copy even earlier,
when I construct stringbuffer instance).

(C++03 instead used the "scanf" family, with
> possible Undefined Behavior). But I think it illustrates the case for wrapping
> in C++.
>
> So, C = preference for codes, error handlers functions etc., and C++ =
> preference for exceptions. But in some cases, as with e.g. calls across binary
> module boundaries, you can't assume C++ exception support. Then you have to
> design for the code to be callable as C, i.e. no exceptions.
>
> All that said, I'm primarily responding because I'm really curious about where
> this great need for MECHANICAL RULES comes from?
>
> If programming could be reduced to mechanical rules, if that was a good idea,
> then, u know, it could be automated, and then you would not have this problem of
> finding the rules because you wouldn't be programming: it would be done by
> machine... So, instead of seeking mechanical rules to be applied mindlessly, I
> suggest seeking up concrete EXAMPLES of failure handling.
> Then apply
> INTELLIGENCE and understanding of concrete situations that you face, and just
> strive to Keep Things Simple. ;-)
Fully agree with all of the above.

>
>
> Cheers & hth.,
>
> - Alf

-Pavel

gremnebulin

unread,
Jun 20, 2012, 3:05:34 PM6/20/12
to
On May 29, 5:15 am, mike3 <mike4...@yahoo.com> wrote:
> Hi.
>
> strings. Would that be OK or excessive use of exceptions? And if we
> are to mix error codes and exceptions, does this mean we should have
> the lists of codes and exceptions correspond + a translator to
> translate between the two?

The problem with both approaches is that you are specifying
implementation directly,
rather than using an interface to specify something which can be
implemented, by someone else, in
different ways. Exception handling is better that error codes because
the whatever handles the exception
can be quite decoupled from the exception raiser, but you still have
the problem that
the exception raising mechanism itself is not always desirable to
employ. A throw is a throw is a throw.

Good error handling should use a wrapper some kind of my_raise_error()
call, an interface that has
no direct meaning to the language in question , and so can be swapped
between various implementational strategies, such as halting
immediately, logging a message, jumping nonlocally, etc, according to
the requirements of the client, and even according to the runtime
environment and
other dynamic factors. It is a common and benevolent pattern for error
handling levels and styles
to be set at programme invocation. Such parameters are a kind of
global variable, but a harmless one
because they are read-only and so do no allow non-local channels of
communication.

my_raise_errors() are usually implemented in a procedural context,
where errors are detected in the first
place with the crappy error_code system. What we still don;t have is
something that gives us the best of both worlds,a system that hast
the expressiveness of try{..}catch{..} and the flexibility
of my_raise_error(), mainly because we don't have user modifiable
syntax in all but experimental languages.




0 new messages