By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 941 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

assert vs error handling

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
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

Jul 23 '05 #2

P: n/a
Christian Christmann wrote:
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?

Jul 23 '05 #3

P: n/a
Christian Christmann wrote:
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.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand
Jul 23 '05 #4

P: n/a
Phlip wrote:
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).
Jul 23 '05 #5

P: n/a
Christian Christmann wrote:
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

Jul 23 '05 #6

P: n/a
Greg wrote:
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.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand
Jul 23 '05 #7

P: n/a
akarl wrote:
Phlip wrote:
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).


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.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand

Jul 23 '05 #8

P: n/a
Greg wrote:
Some programmers do think that assertions and error handling are
roughly synonymous. But they could hardly be more mistaken ...


Please submit your answer to http://www.parashift.com/c++-faq-lite/ .
This really should become a FAQ.

Jul 23 '05 #9

P: n/a


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

Jul 23 '05 #10

P: n/a
msalters wrote:
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...

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand
Jul 23 '05 #11

P: n/a
Greg wrote:
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
Jul 23 '05 #12

P: n/a
akarl wrote:
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.


In that case you are not about to dereference it.

--
Salu2
Jul 23 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.