Understanding Assert and Exceptions

M

mailforpr

Sometimes, I can't think of any good reason why I should have the
program's logic thrown an exception. Except for catching the exception
and printing "Uh, oh" to the screen. I also think that in most cases
there's simply no way to handle an exception properly, because what can
one do about an integer overflow? Reassign values? Restart the program?
The problem will still be existing. I think that an integer overflow is
not an exception, but sluttish programming.

Now I think printing a message "There's a bug - I'm so sorry" is much
better than some bizarre error message provided by the operating
system. Kind of better than assert, which disappears when I compile the
release version and causes the bizarre error message if the bug's still
there.

My conclusion: throwing an exception is still better than assert, for
you can always print a user friendly message to the screen. You could
even provide a dialog or something and ask the user to write down the
steps that caused the bug in a text field.

I saw some guy named "lilburne" say "Use always assert, unless you have
no other choice, but even then consider the exception to be a design
flaw to be eliminated."

Somehow, I agree. After all, if you check for an error condition, then
in some sense you expect it to happen and it is no exception
whatsoever.

Now, if you happen to have any exceptional situations and you deside to
throw an exception, this is more an excuse for poor programming, I
think. Again, what can one do about an integer overflow? Or a wrong
static_cast?

Knowing that something went wrong seems to be the only good point about
exceptions to me anyway. But then again, I am all for assert, as they
don't throw an excuse to the end user. But this has to be done, anyhow.


What do you think?
 
F

Frederick Gotham

posted:
Sometimes, I can't think of any good reason why I should have the
program's logic thrown an exception.


There's isn't really a rule of thumb -- it's intuition more than anything.

My conclusion: throwing an exception is still better than assert, for
you can always print a user friendly message to the screen. You could
even provide a dialog or something and ask the user to write down the
steps that caused the bug in a text field.


Unless, of course, you hijack "assert" and make it more user-friendly.

I saw some guy named "lilburne" say "Use always assert, unless you have
no other choice, but even then consider the exception to be a design
flaw to be eliminated."

Somehow, I agree. After all, if you check for an error condition, then
in some sense you expect it to happen and it is no exception
whatsoever.


People who make blanket rules of thumb like that tend to be improficient.

What do you think?


I use "assert" to indicate that something WRONG... W-R-O-N-G has happened,
such as a letter being '7'.

I throw an exceptio when something exceptional has happened, such as when a
random number is exactly 256.
 
T

Thomas Tutone

Frederick Gotham wrote:

I use "assert" to indicate that something WRONG... W-R-O-N-G has happened,
such as a letter being '7'.

I throw an exceptio when something exceptional has happened, such as when a
random number is exactly 256.

Why would that warrant an exception?

Fred, show us some real code where you would throw an exception in that
instance.

I use exceptions quite a bit (e.g., in a compiler when the source code
has a syntax error), but I don't know anyone who would use an exception
the way you suggest, except in jest.

Best regards,

Tom
 
K

Kai-Uwe Bux

Sometimes, I can't think of any good reason why I should have the
program's logic thrown an exception. Except for catching the exception
and printing "Uh, oh" to the screen. I also think that in most cases
there's simply no way to handle an exception properly, because what can
one do about an integer overflow? Reassign values? Restart the program?
The problem will still be existing. I think that an integer overflow is
not an exception, but sluttish programming.

Now I think printing a message "There's a bug - I'm so sorry" is much
better than some bizarre error message provided by the operating
system. Kind of better than assert, which disappears when I compile the
release version and causes the bizarre error message if the bug's still
there.

My conclusion: throwing an exception is still better than assert, for
you can always print a user friendly message to the screen. You could
even provide a dialog or something and ask the user to write down the
steps that caused the bug in a text field.

I saw some guy named "lilburne" say "Use always assert, unless you have
no other choice, but even then consider the exception to be a design
flaw to be eliminated."

Somehow, I agree. After all, if you check for an error condition, then
in some sense you expect it to happen and it is no exception
whatsoever.

Now, if you happen to have any exceptional situations and you deside to
throw an exception, this is more an excuse for poor programming, I
think. Again, what can one do about an integer overflow? Or a wrong
static_cast?

Those are not examples where exceptions should be used. You use exceptions
to indicate failures that are not bugs. E.g.:

class TCP_Connection {

TCP_Connection ( some args )
: some initializations
{
try to establish the connection.
if you fail, throw an exception indicating the failure.
}

...
};

It is pretty clear that an assert would be wrong: even if your code is 100%
correct, the computers network might just be down. Also, the program can do
something in this case: catch the exception and tell the user to bring up
the network and to try again then.

The point of throwing the exception is to separate concerns: the
TCP_Conncection class could provide handling in place. However, that is
less flexible. It can become unacceptably rigid, if TCP_Connection is part
of a library. Then you want the client to be able to decide how errors
should be handled. Thus, you just throw an exception and let the client
provide the handler. That is what exceptions are designed for: postponing
the handling of resource failures.

Knowing that something went wrong seems to be the only good point about
exceptions to me anyway. But then again, I am all for assert, as they
don't throw an excuse to the end user. But this has to be done, anyhow.

Huh?


Best

Kai-Uwe Bux
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

I saw some guy named "lilburne" say "Use always assert, unless you have
no other choice, but even then consider the exception to be a design
flaw to be eliminated."
Somehow, I agree. After all, if you check for an error condition, then
in some sense you expect it to happen and it is no exception
whatsoever.

Maybe we need a new concept, in addition to exceptions we can introduce
the "impossibilities". Instead of failing an assertion, we throw an
impossibility, like throwing an exception but without any way to catch it
X-)

More seriously: an exception is not (for me and meny others) something I'm
sure will never happen. It's something that, for infrequent of for the way
yo handle it, is better to keep separate from the normal flow.

For example, reaching eof when reading a text file is hardly considered
exceptional, but reaching it in the middle of a field of fixed length in a
binary file is a good candidate for exception.

Maybe this can also be considered a design flaw, we must design systems when
files never are corrupted, disks never fails, users don't make mistakes...
Maybe eliminate users can be a first step in that direction?
 
J

Jim Langston

Sometimes, I can't think of any good reason why I should have the
program's logic thrown an exception. Except for catching the exception
and printing "Uh, oh" to the screen. I also think that in most cases
there's simply no way to handle an exception properly, because what can
one do about an integer overflow? Reassign values? Restart the program?
The problem will still be existing. I think that an integer overflow is
not an exception, but sluttish programming.

Now I think printing a message "There's a bug - I'm so sorry" is much
better than some bizarre error message provided by the operating
system. Kind of better than assert, which disappears when I compile the
release version and causes the bizarre error message if the bug's still
there.

My conclusion: throwing an exception is still better than assert, for
you can always print a user friendly message to the screen. You could
even provide a dialog or something and ask the user to write down the
steps that caused the bug in a text field.

I saw some guy named "lilburne" say "Use always assert, unless you have
no other choice, but even then consider the exception to be a design
flaw to be eliminated."

Somehow, I agree. After all, if you check for an error condition, then
in some sense you expect it to happen and it is no exception
whatsoever.

Now, if you happen to have any exceptional situations and you deside to
throw an exception, this is more an excuse for poor programming, I
think. Again, what can one do about an integer overflow? Or a wrong
static_cast?

Knowing that something went wrong seems to be the only good point about
exceptions to me anyway. But then again, I am all for assert, as they
don't throw an excuse to the end user. But this has to be done, anyhow.


What do you think?

I normally very seldom throw, but I tend to use assert a bit. But there are
good reasons for using throw and catch.

One reason I am doing it is because I have a function that returns a
referernce to a map, although the key may not exist in the map. I got into
a quandry as to what do I return, how do I tell the calling method that the
key was not found, and the best solution I came up with was to throw if it
was not found, and I found out it worked rather well.

CPlayer& FindPlayer( const SOCKET Socket )
{
// Get a reference in the map for this player
map_player::iterator it = World.ConnectedPlayers.find( Socket );
if ( it != World.ConnectedPlayers.end() )
return (*it).second;
else
throw 0;
}

// First lets see if this player is already connected.
try
{
FindPlayer( wsp.Name );
// We didn't throw, so the player name is already logged in
World.MessageBuffer.push_back( LogMessage( "Player " +
jml::StrmConvert( wsp.Name ) + " Tried to log in twice. IP " + IP ) );
return ACCEPT_CLIENT | ( MSG_ALREADY_LOGGED_IN << 8 );
}
catch ( int )
{
}

// later

try
{
CPlayer& ThisPlayer = FindPlayer( Socket );
PlayerLeft( ThisPlayer );
}
catch ( int )
{
World.MessageBuffer.push_back( "Unlogged in socket " +
jml::StrmConvert( Socket ) + " disconnected." );
}

Basically, I will only throw if I can catch it and do something about it,
and there is no better way to handle handle it (return a value from the
function, etc...)

Assert I use only when I want to make sure code isn't running, or that some
value is true when I'm designing. Here's one case (that is actually not
needed)

class CMap
{
private:

// No copy or assignment yet so disable by making private.
CMap ( CMap const& /*CopyThis*/ ) { assert ( false ); }; // Copy
constructor.
CMap& operator=( CMap const& /*CopyThis*/ ) { assert ( false ); }; //
Assignment.
// ...
}

I have made the copy and assignment constructors private beause this class
can not be copied (pointers, etc..) so I just threw the assert in there to
make sure somehow it was never being called (but since it's private, it
shouldn't anyway).

exceptions and assert are tools, and as such should be used when they are
appropriate. It is said that when all you have is a hammer, then everything
starts to look like a nail, but in this case we have many more tools in our
toolboxes.
 
R

Roland Pibinger

The point of throwing the exception is to separate concerns: the
TCP_Conncection class could provide handling in place. However, that is
less flexible. It can become unacceptably rigid, if TCP_Connection is part
of a library. Then you want the client to be able to decide how errors
should be handled. Thus, you just throw an exception and let the client
provide the handler. That is what exceptions are designed for: postponing
the handling of resource failures.


Huh?

assert is a debug aid, ie. the only purpose of assert is to find bugs
in your program. assert is a macro that is not present in the release
version of the program.
OTOH, exceptions indicate expected runtime failures and errors (but
not bugs). They need to be handled (caught) in the program somewhere.
In sum, asserts and exceptions serve different purposes and have
nothing to do with each other.

Best wishes,
Roland Pibinger
 
B

benben

Let's say you are writing a banking program. You are using libraries to
do certain tasks so you don't have to reinvent the wheel. And in one of
the libraries there is one very nifty function:

void perform_transaction();

Now as a user of the library what do you expect when perform_transaction
encounters an exceptional condition such as a runtime error?

What happens if all perform_transaction does is to prints out "Uh, oh,
blah blah blah". Not a good idea because:

1. There is no screen
2. Even if there is a screen it doesn't know what language should be used
3. It fails to stop you, the caller, from doing the next step. If your
next step is to ask the user to pay for the transaction, you will get a
customer complain.

Hope that convinces you that perform_transaction() really shouldn't
handle the exception on its own. What it should do, is to stop the
current transaction and notify you, the caller, what just happened, so
you can handle the problem better because you know if there is a screen,
the language of the customer and how to drop the interaction etc.

Regards,
Ben
 
D

David Harmon

I use "assert" to indicate that something WRONG... W-R-O-N-G has happened,
such as a letter being '7'.

I throw an exceptio when something exceptional has happened, such as when a
random number is exactly 256.

Why would that warrant an exception?[/QUOTE]

It's supposed to be between 0 and 1.
 
D

Duane Hebert

benben said:
Let's say you are writing a banking program. You are using libraries to do
certain tasks so you don't have to reinvent the wheel. And in one of the
libraries there is one very nifty function:

void perform_transaction();

Now as a user of the library what do you expect when perform_transaction
encounters an exceptional condition such as a runtime error?

What happens if all perform_transaction does is to prints out "Uh, oh,
blah blah blah". Not a good idea because:

1. There is no screen
2. Even if there is a screen it doesn't know what language should be used
3. It fails to stop you, the caller, from doing the next step. If your
next step is to ask the user to pay for the transaction, you will get a
customer complain.

Hope that convinces you that perform_transaction() really shouldn't handle
the exception on its own. What it should do, is to stop the current
transaction and notify you, the caller, what just happened, so you can
handle the problem better because you know if there is a screen, the
language of the customer and how to drop the interaction etc.

So what's wrong with it becoming:
bool perform_transaction() and return false on
failure? Personally, I think throwing on a function
failure is bogus. I would reserve exceptions for exceptional
behavior and not for something that can be handled
easily by returning an error.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Duane said:
So what's wrong with it becoming:
bool perform_transaction() and return false on
failure?

Nothing "wrong". You can use any or other way depending on the intended use
of the function.

For example, if the function that calls perform_transaction does not want to
handle the error itself, but let it fall to the callee, it must do
something like:

if (! perform_transaction () )
{
// Maybe some cleaning here.
return false;
}

And with exception you only need:

perform_transaction ();

And the error handling does not get mixed with the normal flow of execution.
 
P

Phlip

mailforpr said:
Sometimes, I can't think of any good reason why I should have the
program's logic thrown an exception.

Write lots of unit tests that crunch your code in various ways.

The situations your tests can't get to, such as a NULL pointer where it
shouldn't be, deserve assert() statements.

The situations they _can_ get to, your users _might_ get to. So that code
should throw assertions, and the test cases should catch them and pass.

Put another way, asserts and exceptions without unit tests are just a
two-legged stool. Not very useful, and no point distinguishing which leg is
which!
 
M

mailforpr

benben said:
What happens if all perform_transaction does is to prints out "Uh, oh,
blah blah blah". Not a good idea because:

1. There is no screen
2. Even if there is a screen it doesn't know what language should be used
3. It fails to stop you, the caller, from doing the next step.

Kai-Uwe Bux said:
Then you want the client to be able to decide how errors
should be handled. Thus, you just throw an exception and let the client
provide the handler. That is what exceptions are designed for: postponing
the handling of resource failures.


I see.
 
D

Duane Hebert

Julián Albo said:
Nothing "wrong". You can use any or other way depending on the intended
use
of the function.

For example, if the function that calls perform_transaction does not want
to
handle the error itself, but let it fall to the callee, it must do
something like:

if (! perform_transaction () )
{
// Maybe some cleaning here.
return false;
}

And with exception you only need:

perform_transaction ();

And the error handling does not get mixed with the normal flow of
execution.

I don't get that. If you don't catch the exception
what is going to happen? At some point you
have to catch it and deal with the error anyway.
 
R

red floyd

Duane said:
I don't get that. If you don't catch the exception
what is going to happen? At some point you
have to catch it and deal with the error anyway.

If an exception is uncaught, eventually terminate() is called, causing
your program to drop dead.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Duane said:
I don't get that. If you don't catch the exception
what is going to happen? At some point you
have to catch it and deal with the error anyway.

The point is that at some point I, or some other programmer that use the
function, can catch the exception. Or just let the program terminate, if
it's a simple command line tool used for people that knows how is written.
 
M

mlimber

Phlip said:
Write lots of unit tests that crunch your code in various ways.

The situations your tests can't get to, such as a NULL pointer where it
shouldn't be, deserve assert() statements.

The situations they _can_ get to, your users _might_ get to. So that code
should throw assertions, and the test cases should catch them and pass.

Put another way, asserts and exceptions without unit tests are just a
two-legged stool. Not very useful, and no point distinguishing which leg is
which!

In many cases, you're right, but in a good many other cases, there is
no practical way to write comprehensive unit tests in any reasonable
amount of time. On a complex embedded system, for instance, one must
accurately simulate the hardware and timing of the system to catch bugs
with unit tests, but doing so is often not feasible. Testing must be
done, of course, but by necessity, it must be to a lesser degree of
thoroughness than some other application domains enjoy.

Cheers! --M
 
P

Phlip

mlimber said:
In many cases, you're right, but in a good many other cases, there is
no practical way to write comprehensive unit tests in any reasonable
amount of time.

If you write them as you write the tested code, you can typically save most
of the time you'd spend debugging.

I use them in this case as an example of exercising the code, to distinguish
accessible but unpreventable problems from programmer errors. There are
other ways.
On a complex embedded system, for instance, one must
accurately simulate the hardware and timing of the system to catch bugs
with unit tests, but doing so is often not feasible. Testing must be
done, of course, but by necessity, it must be to a lesser degree of
thoroughness than some other application domains enjoy.

I thought embedded systems shunned exceptions, and I thought they also
leveraged alternative design techniques.
 
M

mlimber

Phlip said:
If you write them as you write the tested code, you can typically save most
of the time you'd spend debugging.

I use them in this case as an example of exercising the code, to distinguish
accessible but unpreventable problems from programmer errors. There are
other ways.

Sure. But my point was that there are a good number of circumstances
where unit tests are simply not feasible (embedded systems is one,
legacy code with no existing unit tests is another) but where
exceptions and assertions can and should still be used.
I thought embedded systems shunned exceptions, and I thought they also
leveraged alternative design techniques.

Depends on the application of course, but Texas Instrument's (quite
conformant) C++ compiler supports exceptions for their DSPs.

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top