[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: assert vs. abort

From: Ben Pfaff
Subject: Re: assert vs. abort
Date: Sat, 01 Apr 2006 11:16:42 -0800
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/21.4 (gnu/linux)

John Darrington <address@hidden> writes:

> On Fri, Mar 31, 2006 at 10:27:01AM -0800, Ben Pfaff wrote:
>      > The notion (implied by the NDBUG mechanism) that assertions are
>      > something to be disabled in production code is a common one, but one
>      > that I think is misguided.  I would only set NDEBUG in code where
>      > speed is absolutely critical, and pspp doesn't have that criteria.
>      This is a common argument and a very old one; C. A. R. Hoare said
>      something similar, although about array bounds checks, way back
>      in 1972, according to a citation by Knuth.  I sympathize with the
>      sentiment.  But I think it's flawed.


> I didn't say that they should *never* be turned off. I said that
> dogmatically turning them off for production code is not a good idea
> (especially if all the quality assurance tests have been done with
> them turned ON --- it's amazing how many sofware houses do this).

I'm pleased to see that you aren't dogmatic; for some reason, I
assumed, without good evidence, that you were.

>      How about this:
>          ASSERT() -- for cheap, important checks
>          ASSERT1() -- for more expensive or less important checks
>          ASSERT2() -- for expensive checks
>          ASSERT_LEVEL -- if defined to a number, checks at the given
>          level or higher are disabled.
>          NOT_REACHED() -- as discussed
> I'd be reasonably happy with that.  presumably ASSERT{,1,2} simply
> call ASSERT_LEVEL.  And you might want to change 1 & 2 to symbols,
> that way, we can insert a level between 1 and 2 at a later stage if we
> find it becomes necessary.

I meant that ASSERT_LEVEL would be analogous to NDEBUG.
Something like this:

    #ifndef ASSERT_LEVEL
    #define ASSERT_LEVEL 1              /* or whatever default we want */

    #if ASSERT_LEVEL > 2
    #define ASSERT2(EXPR) ((void) 0)

    #if ASSERT_LEVEL > 1
    #define ASSERT1(EXPR) ((void) 0)

    #if ASSERT_LEVEL > 0
    #define ASSERT(EXPR) ((void) 0)

> The question remains then, what level of assertions should be enabled
> when?  
> * I suppose for development all assertions are enabled?
> * Do we want to turn off some/all ASSERTs when doing make dist ?  If
>   so, then we'd have to hack the automake rules, to set the relevant
>   assertion level and do a clean rebuild.

The problem is distinguishing development from deployment.  I
guess make dist would be one way.  But I think it might be
cleaner to just default to some reasonable assertion level
(probably 1 or 2) and then allow developers to override it with a
make flag.

> * NOT_REACHED should *always* be enabled.

...though I'd argue that it should just expand to abort() when
all assertions are otherwise disabled.

> * Some systems I've seen have allow the assert/debug/log level to be
>   set at runtime (through a config file).  Further, some allow  a
>   "domain" flag in addition to  the level (eg {PARSER,OUTPUT,DATA
>   etc}).    Although the   complexity of such systems usually means
>   that most developers don't  understand how to use them, so they
>   either avoid using it, or else they misuse it and thus render it
>   useless for the few people who actually do know how to use it
>   properly. 

I'd like to avoid extra complexity until it's demonstrated to be
Ben Pfaff 
email: address@hidden

reply via email to

[Prev in Thread] Current Thread [Next in Thread]