[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
shrinking "assert (X)" and "abort ()"
From: |
Paul Eggert |
Subject: |
shrinking "assert (X)" and "abort ()" |
Date: |
Fri, 06 May 2011 10:21:42 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110421 Fedora/3.1.9-2.fc14 Thunderbird/3.1.9 |
When NDEBUG is not set, standard implementations of "assert" do something
like this:
#define assert(X) ((void) ((X) || __assert_fail (#X, __FILE__, __LINE__,
__func__))
Sometimes I'd rather have something smaller and faster
in production code, something like this:
#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
#define __builtin_trap() abort ()
#endif
#define assert(X) ((void) ((X) || (__builtin_trap (), 0)))
as this is good enough if you have a debugger, and it prevents code
bloat. For example, with GCC 4.6.0 on x86-64, this would typically
save about 50 bytes of code space per 'assert', or more if the assertion
is a long expression.
Of course I could do this with a new macro (assert_trap, say),
but that'd be an intrusive change into the source code.
I'm thinking of adding a new module, "assert-trap" say, that modifies
assert.h so that "assert" has the above behavior. I know the resulting
assert.h wouldn't conform to the C standard, because the C standard
requires a runtime diagnostic with the file name, but that's OK.
Similarly, I'm thinking of adding a new module "abort-trap" that
does the same for abort (). This wouldn't be as big a savings
-- only 3 bytes of instruction per abort call, on an x86 -- but
it should squeeze more instructions into the cache and thus help
performance in some cases.
Comments?
- shrinking "assert (X)" and "abort ()",
Paul Eggert <=