NDEBUG and assert macros.

Discussion in 'C Programming' started by pereges, Aug 1, 2008.

  1. pereges

    pereges Guest

    Ok, so once I'm done debugging my code(split across multiple modules)
    using the assert macro, I would want to switch off all the assert
    macros ued in the program. Does this mean I have to include:

    #define NDEBUG

    in every .c where I used assert or defining it one file would turn off
    all assert macros in every file ?
     
    pereges, Aug 1, 2008
    #1
    1. Advertising

  2. On 1 Aug, 10:44, pereges <> wrote:

    > Ok, so once I'm done debugging my code(split across multiple modules)
    > using the assert macro, I would want to switch off all the assert
    > macros ued in the program. Does this mean I have to include:
    >
    > #define NDEBUG
    >
    > in every .c where I used assert or defining it one file would turn off
    > all assert macros in every file ?


    It's going to have to be in every compilation unit (c file +
    includes).
    Many compilers support a -D option which enables you to define a macro
    on the compilers command line.

    gcc -DNDEBUG fred.c -ofred

    or you could it in a header file and include the header file
    in every c file. Then at least next time you'd only need
    to change one file.

    Some pitfalls with turning off assert()s. Are you *certain*
    that none of them are essential eg. input validation.
    Are you sure none of them have side effects?

    assert (fopen (s, siseof s, in) != NULL);

    --
    Nick Keighley

    ... it is absurd to make elaborate security checks on
    debugging runs, when no trust is put in the results, and
    then remove them in production runs, when an erroneous
    result could be expensive or disastrous.
    C. A. R. Hoare
     
    Nick Keighley, Aug 1, 2008
    #2
    1. Advertising

  3. pereges <> wrote:
    > Ok, so once I'm done debugging my code(split across multiple modules)
    > using the assert macro, I would want to switch off all the assert
    > macros ued in the program. Does this mean I have to include:


    > #define NDEBUG


    > in every .c where I used assert or defining it one file would turn off
    > all assert macros in every file ?


    Every .c file that uses assert() must see the define. You can achieve
    that by putting the line in every file. On the other hand, in a pro-
    ject with a lot of source files one tends to have a header file that
    gets included everywhere. If you have such a header file than the
    simplest thing would be to put the define in that file.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Aug 1, 2008
    #3
  4. pereges

    rahul Guest

    On Aug 1, 2:44 pm, pereges <> wrote:
    > Ok, so once I'm done debugging my code(split across multiple modules)
    > using the assert macro, I would want to switch off all the assert
    > macros ued in the program. Does this mean I have to include:
    >
    > #define NDEBUG
    >
    > in every .c where I used assert or defining it one file would turn off
    > all assert macros in every file ?


    <off-topic>
    If you compiler supports defining it on invocation, you can have that
    on the command line itself(gcc supports doing that). The general
    approach is to have a Makefile with targets defined for both the
    cases(defined and not defined). Even if you are debugging a single
    file, a simple Makefile won't hurt. That will save you the trouble of
    typing the macro definition again on again while compiling it.
    </off-topic>

    The other approach, would be to have the macro defined in a header
    file and include it in every file you use. Before defining NDEBUG,
    make sure that your assert() is not having any side effects.

    assert ((fp = fopen (FILE_NAME, "rb")) != NULL); /*this will break
    you code

    /* the proper way to do it
    fp = fopen (FILE_NAME, "rb");
    assert (fp != NULL);

    >assert (fopen (s, siseof s, in) != NULL);

    I assume Nick either meant fgets or passed incorrect arguments to
    fopen.
     
    rahul, Aug 1, 2008
    #4
  5. pereges

    Guest

    On Aug 2, 12:54 pm, William Pursell <> wrote:
    > On 1 Aug, 12:31, rahul <> wrote:
    >
    > > /* the proper way to do it
    > > fp = fopen (FILE_NAME, "rb");
    > > assert (fp != NULL);

    >
    > No. Absolutely NOT. This is utterly broken, wrong, and
    > heinous. This is NOT what assert is for. At all. Arghh.


    It might not be what assert is for, but it's not broken or wrong. (if
    you don't mind the missing */)

    <snip>
     
    , Aug 2, 2008
    #5
  6. pereges

    santosh Guest

    William Pursell wrote:

    > On 1 Aug, 12:31, rahul <> wrote:
    >
    >
    >> /* the proper way to do it
    >> fp = fopen (FILE_NAME, "rb");
    >> assert (fp != NULL);

    >
    > No. Absolutely NOT. This is utterly broken, wrong, and
    > heinous. This is NOT what assert is for. At all. Arghh.
    > If you want, you might do:
    >
    > fp = Fopen( ... );
    > assert( fp != NULL );
    >
    > This would serve as documentation to the maintainer that
    > the Fopen call will never return a NULL pointer. Or you
    > can do things like:
    >
    > for( i = 0; i < N; i++) {
    > ...
    > }
    > assert( i == N);
    >
    > This documents to the maintainer that the loop
    > is constructed such that it will always terminate with i
    > hitting the upper bound. The purpose of assert is to
    > validate that something you believe must be true is
    > in fact true. Often as pre-conditions in a function call:
    >
    > void add( const int *a, const int *b, int *c, size_t N )
    > {
    > size_t i;
    > assert( a != NULL );
    > assert( b != NULL );
    > assert( c != NULL );
    >
    > for( i = 0; i < N; i++ )
    > c = a + b;
    > }
    >
    > This is far safer than simply adding a comment that states
    > that none of the arguments can be a null pointer, since it
    > aborts when the unwary programmer attempts to pass a null
    > pointer. It is NOT doing validation. If you want to write
    > a function that validates, you can't use assert. For example:
    >
    > int add( int *a, int *b, int *c)
    > {
    > int status = 0;
    > int A,B;
    >
    > A = ( a == NULL ) ? 0 : *a;
    > B = ( b == NULL ) ? 0 : *b;
    > if( c == NULL )


    But is it any more correct call this add with null pointer values
    for 'a', 'b', or 'c' than a similar call of the previous add? Why would
    one want to write a zero to *c when the function is called with clearly
    invalid arguments. I personally would return the error value for all
    these cases, not just when c is NULL.

    I can't really decide whether using assert on function parameters is
    appropriate or not. An error code, as in this code, might be silently
    misused by the caller, but OTOH, it somehow seems better to *inform*
    the caller of an erroneous call (thus giving it a chance to retry,
    though how much real life code is this comprehensive?), than terminate
    the program single-handedly. But then would checking parameters with
    assert be more justified for a function that has no defined error
    return codes?

    IMHO assert seems much more appropriate when used to verify the
    correctness of program state at various points than when it's used for
    things like function parameter checking, return value checking etc.

    > status = -1
    > else
    > *c = A + B;
    > return status;
    > }
    >
    > Here, there are some questions. For example, perhaps you want
    > this function to never overflow. So perhaps you might want to
    > ensure that it is never called with *a or *b larger than INT_MAX/2.
    > In that case, look through your code; if you believe that
    > condition is true, then make it an assertion.


    In the calling code? If so I agree.

    <snip>
     
    santosh, Aug 2, 2008
    #6
    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:
    519
    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,567
    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:
    960
    Keith Thompson
    Nov 25, 2004
  4. Alex Vinokur
    Replies:
    2
    Views:
    572
    Eric Sosman
    Jan 7, 2009
  5. ImpalerCore

    To assert or not to assert...

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

Share This Page