[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 */
#endif
#if ASSERT_LEVEL > 2
#define ASSERT2(EXPR) ASSERT_CHECK(EXPR)
#else
#define ASSERT2(EXPR) ((void) 0)
#endif
#if ASSERT_LEVEL > 1
#define ASSERT1(EXPR) ASSERT_CHECK(EXPR)
#else
#define ASSERT1(EXPR) ((void) 0)
#endif
#if ASSERT_LEVEL > 0
#define ASSERT(EXPR) ASSERT_CHECK(EXPR)
#else
#define ASSERT(EXPR) ((void) 0)
#endif
> 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
useful.
--
Ben Pfaff
email: address@hidden
web: http://benpfaff.org
- Re: assert vs. abort,
Ben Pfaff <=