assert vs error handling

  • Thread starter Christian Christmann
  • Start date
C

Christian Christmann

Hi,

assert and error handling can be used for similar purposes.

When should one use assert instead of try/catch and in which
cases the error handling is preferable?

I've read somewhere that assert could be used to start
an interactive debugger automatically. How do I realize that
on a Linux machine using gcc?

Thank you

Chris
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

I don't think you want to try this.
If an assertion fails, you call a function void doDebug(),
instead of the usual abort() that is called from assert(...).

Then start the debugger, set a breakpoint to doDebug()
and run the program.
If an assertion fails, the debugger will stop and by moving
one step up you can examine the situation.

Stephan
 
M

Mercator

Christian said:
assert and error handling can be used for similar purposes.

No, quite the contrary!!
When should one use assert instead of try/catch and in which
cases the error handling is preferable?

'assert' is for finding bugs in your code in a 'Debug build' (no
asserts remain in the Release build). Exceptions are for gracefully
handling unexpected situations at runtime. Two entirely different use
cases.
I've read somewhere that assert could be used to start
an interactive debugger automatically. How do I realize that
on a Linux machine using gcc?

Never needed that. Isn't it enough that the program prints the
offending line of code?
 
P

Phlip

Christian said:
assert and error handling can be used for similar purposes.

When should one use assert instead of try/catch and in which
cases the error handling is preferable?

Assertions are for programming errors, and error handling is for bad input.

When in doubt, handle an error.
I've read somewhere that assert could be used to start
an interactive debugger automatically. How do I realize that
on a Linux machine using gcc?

On Win32 x86 it's __asm { int 3 };

Someone else will know for Linux. That's the joy of posting an off-topic
question!

Now start writing unit tests, and put all your assertions in there.
Including assertions that bad inputs invoke error handlers.
 
A

akarl

Phlip said:
Assertions are for programming errors, and error handling is for bad input.

I think assertions is often used to check for bad input (preconditions)
as well as for postconditions (design by contract).
 
G

Greg

Christian said:
Hi,

assert and error handling can be used for similar purposes.

When should one use assert instead of try/catch and in which
cases the error handling is preferable?

I've read somewhere that assert could be used to start
an interactive debugger automatically. How do I realize that
on a Linux machine using gcc?

Thank you

Chris

Some programmers do think that assertions and error handling are
roughly synonymous. But they could hardly be more mistaken. Asserted
conditions and error handling are in fact two unrelated programming
practices that should always be carefully distinguished from one
another. Much of the difficulty in communicating the distinction, I
believe, derives from the fact that the word "error" figures
prominently in the descriptions of each of them. But the types of
errors referred to in either case, are completely different.

Assert expressions are used to find programming errors: either errors
in the program's logic itself or in errors in its corresponding
implementation. An assert condition verifies that the program remains
in a defined state. A "defined state" is basically one that agrees with
the program's assumptions. Note that a "defined state" for a program
need not be an "ideal state" or even "a usual state", or even a "useful
state" but more on that important point later.

To understand how assertions fit into a program, consider a routine in
a C++ program that is about to dereference a pointer. Now should the
routine test whether the pointer is NULL before the dereferencing, or
should it assert that the pointer is not NULL and then go ahead and
dereference it regardless?

I imagine that most developers would want to do both, add the assert,
but also check the pointer for a NULL value, in order not to crash
should the asserted condition fail. On the surface, performing both the
test and the check may seem the wisest decision. But such a decision
shows that information is actually lacking. The programmer does not
know whether a NULL pointer in this situation means that the program is
in undefined state or not. But the program is in one state or the
other. If the pointer is not NULL in every one of the program's defined
states than the assert's NULL check is sufficient. Whatever the program
does afterwards is not covered by the program's design. The best that
can happen is the the program crashes right away. On the other hand, if
the pointer being NULL does not place the application in an undefined
state, then not to check it for a NULL value would be a programming
error before dereferencing it. By the same token, the program's remains
in a defined state regardless of a NULL-valued pointer, so an assert on
the pointer's value would not an assertable condition.

Unlike its asserted conditions, a program's error handling refers not
to errors in the program, but to inputs the program obtains from its
environment. These are often "errors" on someone's part, such as a user
attempting to login to an account without typing in a password. And
even though the error may prevent a successful completion of program's
task, there is no program failure. The program fails to login the user
without a password due to an external error - an error on the user's
part. If the circumstances were different, and the user typed in the
correct password and the program failed to recognize it; then although
the outcome would still be the same, the failure would now belong to
the program.

The purpose of error handling is two fold. The first is to communicate
to the user (or some other client) that an error in program's input has
been detected and what it means. The second aim is to restore the
application after the error is detected, to a well-defined state. Note
that the program itself is not in error in this situation. Granted, the
program may be in a non-ideal state, or even a state in which can do
nothing useful, but there is no programming errorl. On the contrary,
since the error recovery state is one anticipated by the program's
design, it iss one that the program can handle.

To communicate runtime errors, developers will often use asserted
conditions. Unfortunately, this practice further blurs the distinction
between the program's defined and undefined states and between external
and internal errors. For example, testing whether a network server is
reachable is probably not a reasonable asserted condition for a network
application. Unless it is OK to expect the program to crash whenever a
server becomes unreachable, the program should be able to handle this
situation. On the other hand, it is important to convey to a tester
that the reason that the network server cannot be reached is due to an
external condition, and not due to a programming error.

To report external error conditions, I would recommend adopting an
assert-like mechanism, but one that carefully distinguishes these type
of reports from true assertion failures - which are, and should always
be, the detection of a programming error. The rule of thumb should be:
if a program does not crash after an assertion failure then the bug is
either a bogus asserted condition, or a failure in the program's logic
that prevents the program from crashing when it should.

Greg
 
P

Phlip

Greg said:
To understand how assertions fit into a program, consider a routine in
a C++ program that is about to dereference a pointer. Now should the
routine test whether the pointer is NULL before the dereferencing, or
should it assert that the pointer is not NULL and then go ahead and
dereference it regardless?

I imagine that most developers would want to do both, add the assert,
but also check the pointer for a NULL value, in order not to crash
should the asserted condition fail. On the surface, performing both the
test and the check may seem the wisest decision. But such a decision
shows that information is actually lacking. The programmer does not
know whether a NULL pointer in this situation means that the program is
in undefined state or not. But the program is in one state or the
other. If the pointer is not NULL in every one of the program's defined
states than the assert's NULL check is sufficient. Whatever the program
does afterwards is not covered by the program's design. The best that
can happen is the the program crashes right away. On the other hand, if
the pointer being NULL does not place the application in an undefined
state, then not to check it for a NULL value would be a programming
error before dereferencing it. By the same token, the program's remains
in a defined state regardless of a NULL-valued pointer, so an assert on
the pointer's value would not an assertable condition.

Hence the value of "unit" tests. If you can write a test case that
legitimately forces a NULL (such as by deleting the program's favorite
file), then you can write an 'if' statement to recover.

If you can't force the situation, add an assertion and keep going.

Note the test case may force a bad situation that client code cannot force.
Hence tests pressure code to grow more robust.
 
P

Phlip

akarl said:
Phlip wrote: input.

I think assertions is often used to check for bad input (preconditions)
as well as for postconditions (design by contract).

DbC is magic, and C++ code should not flatter it by imitation.

Without the magic of a fully DbC aware compiler and language definition, an
assertion for a precondition devolves into a feeble attempt to test the
function that called the assertive function.

So, it looks like we are back to automated test cases. They test the calling
function directly, and with a range of data.
 
M

msalters

Christian Christmann schreef:
Hi,

assert and error handling can be used for similar purposes.

No. Assertions are essentially comments. i.e. assert( i>5 );
is a better way to write /* after calling foo(), i>5 */
Error handling obviously is not a comment because it affects
functionality.

Regards,
Michiel Salters
 
P

Phlip

msalters said:
No. Assertions are essentially comments. i.e. assert( i>5 );
is a better way to write /* after calling foo(), i>5 */

Yay! Hence the "Introduce Assertion Refactor"!

Its canonic form replaces a comment with an assertion...
 
A

akarl

Greg said:
To understand how assertions fit into a program, consider a routine in
a C++ program that is about to dereference a pointer. Now should the
routine test whether the pointer is NULL before the dereferencing, or
should it assert that the pointer is not NULL and then go ahead and
dereference it regardless?

It depends on the situation. assert(p != NULL) means "p shouldn't be
NULL", whereas if we e.g. are traversing a linked list we will
eventually compare a pointer to NULL, it's expected that the pointer
will become NULL.
Unlike its asserted conditions, a program's error handling refers not
to errors in the program, but to inputs the program obtains from its
environment. These are often "errors" on someone's part, such as a user
attempting to login to an account without typing in a password. And
even though the error may prevent a successful completion of program's
task, there is no program failure. The program fails to login the user
without a password due to an external error - an error on the user's
part. If the circumstances were different, and the user typed in the
correct password and the program failed to recognize it; then although
the outcome would still be the same, the failure would now belong to
the program.

Bad input (invalid values of function parameters) can also occur when a
client is using a library in the wrong way so the distinction is not
nessecarily that clear.

August
 
?

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

akarl said:
It depends on the situation. assert(p != NULL) means "p shouldn't be
NULL", whereas if we e.g. are traversing a linked list we will
eventually compare a pointer to NULL, it's expected that the pointer
will become NULL.

In that case you are not about to dereference it.
 

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,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top