assert vs error handling

Discussion in 'C++' started by Christian Christmann, Jul 17, 2005.

  1. 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
    Christian Christmann, Jul 17, 2005
    #1
    1. Advertising

  2. 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
    =?iso-8859-1?q?Stephan_Br=F6nnimann?=, Jul 17, 2005
    #2
    1. Advertising

  3. Christian Christmann

    Mercator Guest

    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?
    Mercator, Jul 17, 2005
    #3
  4. Christian Christmann

    Phlip Guest

    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
    Phlip, Jul 17, 2005
    #4
  5. Christian Christmann

    akarl Guest

    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).
    akarl, Jul 18, 2005
    #5
  6. Christian Christmann

    Greg Guest

    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
    Greg, Jul 18, 2005
    #6
  7. Christian Christmann

    Phlip Guest

    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
    Phlip, Jul 18, 2005
    #7
  8. Christian Christmann

    Phlip Guest

    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
    Phlip, Jul 18, 2005
    #8
  9. Christian Christmann

    Mercator Guest

    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.
    Mercator, Jul 18, 2005
    #9
  10. Christian Christmann

    msalters Guest

    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
    msalters, Jul 18, 2005
    #10
  11. Christian Christmann

    Phlip Guest

    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
    Phlip, Jul 18, 2005
    #11
  12. Christian Christmann

    akarl Guest

    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
    akarl, Jul 18, 2005
    #12
  13. 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
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Jul 18, 2005
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Brewer
    Replies:
    1
    Views:
    481
    bsmith
    Nov 7, 2004
  2. Thomas Guettler

    assert 0, "foo" vs. assert(0, "foo")

    Thomas Guettler, Feb 23, 2005, in forum: Python
    Replies:
    3
    Views:
    2,502
    Carl Banks
    Feb 23, 2005
  3. Alex Vinokur

    assert(x) and '#define ASSERT(x) assert(x)'

    Alex Vinokur, Nov 25, 2004, in forum: C Programming
    Replies:
    5
    Views:
    897
    Keith Thompson
    Nov 25, 2004
  4. Tim Arnold

    pypdf assert error on documentinfo

    Tim Arnold, Jun 28, 2007, in forum: Python
    Replies:
    0
    Views:
    395
    Tim Arnold
    Jun 28, 2007
  5. ImpalerCore

    To assert or not to assert...

    ImpalerCore, Apr 27, 2010, in forum: C Programming
    Replies:
    79
    Views:
    1,637
    Richard Bos
    May 17, 2010
Loading...

Share This Page