C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Error codes vs. exceptions
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Shane Groff
Guest





PostPosted: Sun Oct 10, 2004 10:25 pm    Post subject: Error codes vs. exceptions Reply with quote



I know this is a recurring discussion (I've spent the last 3 days
reading through threads on the topic), but I feel compelled to start
it up again.

After reading through the existing threads, I find myself convinced
that exceptions are a better mechanism, for example because
constructors and operators can't return errors, and code that doesn't
need to handle/translate/recover in the face of errors, but can just
propagate the error is cleaner with exceptions.

However, those reasons are often not compelling enough to convince
people who don't like exceptions (usually in my experience because
they incorrectly think that exceptions are more 'dangerous' somehow
than error codes, when in fact, they just don't see that it is just as
dangerous to ignore an error code as it is to not handle an exception
when it should be).

Consider this idiom when using error codes:

ErrorCode EcFoo()
{
ErrorCode ec;
Check(EcBar());
Check(EcBletch());
...
Exit:
return (ec);
}

Here, Check is a macro that checks the return code and jumps to Exit
if an error occurs.

Using this pattern, we avoid the appearance of a slew of if/then
statments (although they are there, of course, just hidden by the
preprocessor).

This makes the code almost as straightforward as the exception case,
and doesn't introduce much overhead (space or time), since it is
basically just adding a check for 0 to each call.

This addresses some of the problems I've seen leveled against error
codes. Although it seems to me that we're just writing what amounts to
our own equivalent to exceptions here (for example, functions that
don't handle the error don't need to do any 'additional' work to
propagate the error, assuming they are following the pattern), some
people are more comfortable with this because they know that returning
and checking for error codes is always fairly inexpensive, while
throwing an exception can be expensive.

Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Joshua Lehrer
Guest





PostPosted: Mon Oct 11, 2004 11:29 am    Post subject: Re: Error codes vs. exceptions Reply with quote



[email]shane (AT) shaneandsusan (DOT) com[/email] (Shane Groff) wrote in message news:<78817520.0410091638.459684d9 (AT) posting (DOT) google.com>...
Quote:
ErrorCode EcFoo()
{
ErrorCode ec;
Check(EcBar());
Check(EcBletch());
...
Exit:
return (ec);
}

Here, Check is a macro that checks the return code and jumps to Exit
if an error occurs.


Among the problems with this approach is an inability to declare stack
based objects between the first "check" and the label "Exit". My
compiler gives the error:

"Transfer of control bypasses initialization of variable
"variable_name".

This makes sense. When the compiler gets to "return (ec);", it must
assume that all objects in the current scope have been initialized.
However, if you jump over the declaration of an object, then it has
not been initialized once the return statement is reached.

6.7.3 states:

It is possible to transfer into a block, but not in a way that
bypasses declarations with initialization. A program that jumps from a
point where a local variable with automatic storage duration is not in
scope to a point where it is in scope is illformed unless the variable
has POD type (3.9) and is declared without an initializer (8.5).

joshua lehrer
factset research systems
NYSE:FDS

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Mon Oct 11, 2004 11:12 pm    Post subject: Re: Error codes vs. exceptions Reply with quote



[email]shane (AT) shaneandsusan (DOT) com[/email] (Shane Groff) wrote (abridged):
Quote:
Here, Check is a macro that checks the return code and jumps to Exit
if an error occurs.

The jump is problematic; it might try to skip over constructors or
destructors, which will give compiler errors. You might try using return
instead. You can probably eliminate the need to declare a variable in
advance, too. Along the lines of (untested):

struct EcChecker {
ErrorCode ec;
EcChecker( ErrorCode ec ) : ec(ec) {}
operator bool() const { return ec != EC_OK; }
};

#define ReturnOnError( f )
if (EcChecker checker( f ))
return checker.ec;

ErrorCode EcFoo() {
ReturnOnError( EcBar() );
ReturnOnError( EcBletch() );
return EC_OK;
}


Quote:
Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

That depends on why they are reluctant. There are valid arguments against
them.

Exceptions have the advantage that they free the function's result for
something more useful. Compare:

ErrorCode move_window( Wnd *pWnd, Offset offset ) {
Rectangle position;
ReturnOnError( pWnd->get_position( &position ) );
position += offset;
ReturnOnError( pWnd->set_position( position ) );
return EC_OK;
}

with:

void move_window( Wnd *pWnd, Offset offset ) {
pWnd->set_position( pWnd->position() + offset );
}

Exceptions make it easier to write in functional style, with
function-composition instead of side effects on arguments. I find this
clearer as well as shorter.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gerhard Menzl
Guest





PostPosted: Mon Oct 11, 2004 11:13 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

Shane Groff wrote:

Quote:
Consider this idiom when using error codes:

ErrorCode EcFoo()
{
ErrorCode ec;
Check(EcBar());
Check(EcBletch());
...
Exit:
return (ec);
}

Here, Check is a macro that checks the return code and jumps to Exit
if an error occurs.

Using this pattern, we avoid the appearance of a slew of if/then
statments (although they are there, of course, just hidden by the
preprocessor).

This makes the code almost as straightforward as the exception case,
and doesn't introduce much overhead (space or time), since it is
basically just adding a check for 0 to each call.

This addresses some of the problems I've seen leveled against error
codes. Although it seems to me that we're just writing what amounts to
our own equivalent to exceptions here (for example, functions that
don't handle the error don't need to do any 'additional' work to
propagate the error, assuming they are following the pattern), some
people are more comfortable with this because they know that returning
and checking for error codes is always fairly inexpensive, while
throwing an exception can be expensive.

Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

Two key objections off my cuff:

1. You need to repeat the exercise for every function, even if all it
does is to propagate the error to its caller. Exceptions do not suffer
from this drawback, hence they make the normal flow of control less
expensive. When an error that is serious enough to justify an exception
occurs, stack unwinding efficiency is probably the least of your worries.

2. As exceptions become more commonplace and find their way into
third-party interfaces, you need to write exception-aware code anyway.
This means that you get two competing error handling mechanisms:
Standard C++ exceptions, and your roll-your-own type, resulting in code
that is more complicated, more difficult to understand, and probably
even less efficient.

--
Gerhard Menzl

Humans may reply by replacing the obviously faked part of my e-mail
address with "kapsch".

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hyman Rosen
Guest





PostPosted: Mon Oct 11, 2004 11:38 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

Shane Groff wrote:
Quote:
Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

In the presumably more common case of no error,
this version executes a bunch of extra code, namely
all of those if statements. This makes the code less
efficient than the exception version.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Shane Groff
Guest





PostPosted: Tue Oct 12, 2004 10:39 am    Post subject: Re: Error codes vs. exceptions Reply with quote

[email]usenet_cpp (AT) lehrerfamily (DOT) com[/email] (Joshua Lehrer) wrote in message news:<31c49f0d.0410101916.6d79758 (AT) posting (DOT) google.com>...
Quote:
shane (AT) shaneandsusan (DOT) com (Shane Groff) wrote in message news:<78817520.0410091638.459684d9 (AT) posting (DOT) google.com>...
ErrorCode EcFoo()
{
ErrorCode ec;
Check(EcBar());
Check(EcBletch());
...
Exit:
return (ec);
}

Here, Check is a macro that checks the return code and jumps to Exit
if an error occurs.


Among the problems with this approach is an inability to declare stack
based objects between the first "check" and the label "Exit". My
compiler gives the error:

"Transfer of control bypasses initialization of variable
"variable_name".

This makes sense. When the compiler gets to "return (ec);", it must
assume that all objects in the current scope have been initialized.
However, if you jump over the declaration of an object, then it has
not been initialized once the return statement is reached.

6.7.3 states:

It is possible to transfer into a block, but not in a way that
bypasses declarations with initialization. A program that jumps from a
point where a local variable with automatic storage duration is not in
scope to a point where it is in scope is illformed unless the variable
has POD type (3.9) and is declared without an initializer (8.5).


You're right, of course, this pattern requires that all objects be
declared at the beginning of a scope. However, some people prefer
this, anyway, since it makes it easier to find the declaration of
local variables within a function. It has the drawback that you may
not have all the information you want to construct an object, which
may require that you do something like construct a default object and
then update its state, but I don't think this is a compelling reason
to avoid the pattern (For example, I think it's worse that if you are
avoiding exceptions, you have to either do a two-phase constructor
that won't fail + init member, or have the object set some member
indicating that it could not properly construct).

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrew Koenig
Guest





PostPosted: Tue Oct 12, 2004 10:44 am    Post subject: Re: Error codes vs. exceptions Reply with quote

"Shane Groff" <shane (AT) shaneandsusan (DOT) com> wrote


Quote:
Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

What do you do about programmers who forget or neglect to check for the
presence of error codes?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pierre Baillargeon
Guest





PostPosted: Tue Oct 12, 2004 10:01 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

Quote:
usenet_cpp (AT) lehrerfamily (DOT) com (Joshua Lehrer) wrote in message news:<31c49f0d.0410101916.6d79758 (AT) posting (DOT) google.com>...

Among the problems with this approach is an inability to declare stack
based objects between the first "check" and the label "Exit". My
compiler gives the error:

"Transfer of control bypasses initialization of variable
"variable_name".

This makes sense. When the compiler gets to "return (ec);", it must

Red herring:: just declare new scopes where you need new variables.

One problem with exceptions is that you cannot have compiler-enforced
checking that the exception is actually handled (unless you a compiler
doing whole-program analysis). On many compilers you can turn on
warning about unused return values. So score one for return values.

Another problem is mess scope: an unused return code will mess up
locally (but the failure to detect can have global consequence), but
unhandled exception can propagate way beyond the intended scope, even
crashing the program.

People tend to over exagerate the problem of ignored return values.
Most errors are persistent: if not detected the first time, it will be
detected soon thereafter and the error state of the underlying system
is persistent and will do no harm. Most error-returning design are
written this way out of hard-learned experience... So programs are
more resilient than acknowledged. For example, when doing formatted
I/O in C++, most people will check the error state at the end of
output, not after each operation... the streams are designed that way
for this reason.

The other problem with exceptions is that it can be hard to decide if
a particular operation has a common or rare error case. Most people
advocating exceptions agree that for functions that fail often, it
still is better to use return code, because exception- handling is
still awkward and verbose. I can tell you from experience that
choosing to throw when the common case is error will make people curse
you and ask over and over why did you choose to throw for this
particular operation... sigh, hindsight is 100%.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
David Abrahams
Guest





PostPosted: Tue Oct 12, 2004 10:07 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

"Andrew Koenig" <ark (AT) acm (DOT) org> writes:

Quote:
"Shane Groff" <shane (AT) shaneandsusan (DOT) com> wrote in message
news:78817520.0410091638.459684d9 (AT) posting (DOT) google.com...

Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

What do you do about programmers who forget or neglect to check for the
presence of error codes?

I think there are good arguments for using exceptions, but I'm not
sure this is one of them. A programmer that treats functions that can
throw as though they can't throw is likewise going to write buggy
code. I'm not sure the problems are any worse in either case.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Steve Richter
Guest





PostPosted: Tue Oct 12, 2004 10:31 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

"Andrew Koenig" <ark (AT) acm (DOT) org> wrote

Quote:
"Shane Groff" <shane (AT) shaneandsusan (DOT) com> wrote in message
news:78817520.0410091638.459684d9 (AT) posting (DOT) google.com...

Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

What do you do about programmers who forget or neglect to check for the
presence of error codes?

well you could wrap the return code in a class that throws an
exception if the contents of the return code are not queried, that is
used on the RHS of an expression.

class ReturnCode
{
enum eSeverity { severityOk, severityError } ;
int mnActualValue ;
bool mbWasAccessed ;
eSeverity meSeverity ;

operator int( )
{ mbWasAccessed = true ; return mnActualValue ; }
ReturnCode( int nActualValue, eSeverity es )
{ mbWasAccessed = false ; mnActualValue = nActualValue ;
meSeverity = es ; }
~ReturnCode( )
{ if (( mbWasAccessed == false ) && ( meSeverity == severityError
))
throw( "you did not chk the rtn code!" ) ; }
} ;

ReturnCode DoSomething( )
{
if ( whatever )
return( ReturnCode( 0, ReturnCode::severityOk )) ;
else
return( ReturnCode( 99, ReturnCode::severityError )) ;
}

void MainLine( )
{
// the return code ends up in nRc. trust the programmer
// does something with it.
int nRc = DoSomething( ) ;

// the code is not "catching" the return code. the ReturnCode
// object throws an exception if the code has a severity of
// severityError.
DoSomething( ) ;

}

the advantage is that you dont have to clutter your code with the try
and catch statments. A more important advantage is that you know
there is a major problem when the ReturnCode class is going to throw
its "you did not catch this error" exception. So the throw code can
put up a prompt saying "this program has bombed, here is the call
stack, here is the error code. Call data processing for assistance."
That course of action is not generally possible when your code throws
an exception. You dont know at throw time if the exception will be
caught or not.

-Steve

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Shane Groff
Guest





PostPosted: Tue Oct 12, 2004 10:32 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

"Andrew Koenig" <ark (AT) acm (DOT) org> wrote

Quote:
"Shane Groff" <shane (AT) shaneandsusan (DOT) com> wrote in message
news:78817520.0410091638.459684d9 (AT) posting (DOT) google.com...

Any specific thoughts on the idiom, or compelling arguments to offer
for the use of exceptions to the reluctant?

What do you do about programmers who forget or neglect to check for the
presence of error codes?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Shoot them?

Yes, that's a problem.

One of the reasons people like this is that if they decide to use a
function that may return an error, but in this particular caller, they
don't care (the popular example I've seen is a call to log to a
database, writing to the database clearly might fail, but if the log
is just informational, not critical to the callers functionality, it's
OK if it fails), then they can just not check the error code. Of
course, I argue that's a bad thing to do, because then when reading
the code, I can't tell if they ignored the error on purpose or not
(they could add a comment, but that has its own problems). I'm of the
opinion that regardless of the error mechanism, if you want to have a
function that does something, and you don't care if it succeeds or
not, you should wrap the error-reporting function into a new function
that doesn't report errors anyway to make it clear.

That said, there are 'bad things' a programmer can do with exceptions
as well, especially if they aren't in the practice of of using RAII
(like allocating an object with new, and not assigning it to an
auto_ptr, or some other owning object). In the error code mechasnism
above, they would probably free the object after the label.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Niklas Matthies
Guest





PostPosted: Wed Oct 13, 2004 11:33 am    Post subject: Re: Error codes vs. exceptions Reply with quote

On 2004-10-12 22:32, Shane Groff wrote:
:
Quote:
One of the reasons people like this is that if they decide to use a
function that may return an error, but in this particular caller, they
don't care (the popular example I've seen is a call to log to a
database, writing to the database clearly might fail, but if the log
is just informational, not critical to the callers functionality, it's
OK if it fails), then they can just not check the error code. Of
course, I argue that's a bad thing to do, because then when reading
the code, I can't tell if they ignored the error on purpose or not
(they could add a comment, but that has its own problems).

A common C idiom is to cast ignored return values to void, as in

(void) do_stuff(foo, bar);

which also (in general) silences compiler warnings about unused
return values. So the cast signals that ignoring the return value
is intentional here. Any ignored return value not cast to void
should be highly suspicious (and warned about by the compiler).

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jim Melton
Guest





PostPosted: Wed Oct 13, 2004 11:34 am    Post subject: Re: Error codes vs. exceptions Reply with quote

"Shane Groff" <shane (AT) shaneandsusan (DOT) com> wrote

Quote:
You're right, of course, this pattern requires that all objects be
declared at the beginning of a scope. However, some people prefer
this, anyway, since it makes it easier to find the declaration of
local variables within a function.

This is a bit off from your original question, but I wouldn't be so quick to
accept this as a desirable construct. Declaring variables at the point of
first use actually decreases complexity of your programs, and is a practice
that should be encouraged. If someone wants to find the declaration of a
variable, they should either use an IDE or get familiar with their editor's
search function.

Quote:
It has the drawback that you may
not have all the information you want to construct an object, which
may require that you do something like construct a default object and
then update its state, but I don't think this is a compelling reason
to avoid the pattern (For example, I think it's worse that if you are
avoiding exceptions, you have to either do a two-phase constructor
that won't fail + init member, or have the object set some member
indicating that it could not properly construct).

Actually, you are requiring that all your objects HAVE a default-constructed
state... an unreasonable requirement to me. There are other patterns for
error code checking that are preferable to this goto-based approach in my
mind.

Also, bear in mind that your pattern still relies on the programmer to be
diligent to invoke your macro for functions that return an error code (and
that all error codes have the same success/failure values?).

I'm not persuaded.
--
<disclaimer>
Opinions posted are those of the author.
My company doesn't pay me enough to speak for them.
</disclaimer>
--
Jim Melton
Software Architect, Fusion Programs
Lockheed Martin IS&S
(303) 971-3846




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Abrahams
Guest





PostPosted: Wed Oct 13, 2004 9:16 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

[email]srichter (AT) autocoder (DOT) com[/email] (Steve Richter) writes:

Quote:
well you could wrap the return code in a class that throws an
exception if the contents of the return code are not queried, that is
used on the RHS of an expression.

<snip>

Quote:
the advantage is that you dont have to clutter your code with the try
and catch statments.

If your code is cluttered with try and catch blocks you're not "doing
exception safety" very effectively. In fact, if you substitute error
codes for exceptions you are very likely to clutter your code with
error checks that could otherwise have been avoided.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Wed Oct 13, 2004 9:32 pm    Post subject: Re: Error codes vs. exceptions Reply with quote

In article <slrncmosr4.2jg.usenet-nospam (AT) nmhq (DOT) net>, Niklas Matthies
<usenet-nospam (AT) nmhq (DOT) net> writes
Quote:
A common C idiom is to cast ignored return values to void, as in

(void) do_stuff(foo, bar);

Not really that common, and only used where early versions of lint
generated excessive warnings.

Quote:

which also (in general) silences compiler warnings about unused
return values. So the cast signals that ignoring the return value
is intentional here. Any ignored return value not cast to void
should be highly suspicious (and warned about by the compiler).

Frankly I would not want to use a compiler that gave me warnings about
unused return values. The use of such functions is pervasive in both C
and C++ and I would either have to clutter my code with pointless casts
or find that real, valuable warnings were being missed in the clutter.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.