[RFC/PATCH] Optimize code based on asserts even in NDEBUG mode

Alex Rosenberg alexr@spies.com
Fri Apr 9 20:06:00 GMT 2004


On Apr 9, 2004, at 2:22 AM, Paolo Bonzini wrote:

> This patch optimizes code in NDEBUG mode based on the conditions
> that the program asserts.  This patch, in other words, allows a
> function like this
>
>  #include <assert.h>
>  #define NDEBUG
>
>  int f(char *x)
>  {
>    assert (x != NULL);
>    return x ? *x : 0;
>  }
>
> to be compiled simply as
>
>         movl    4(%esp), %eax
>         movsbl  (%eax), %eax
>         ret
>
> The trick is to have assert invoke a const/noreturn function (returning
> void) in NDEBUG mode, and to remove such invocations in ifcvt.  I see
> that this may likely not be the best way, hence the RFC.  To link
> this to assert, there will be a GCC-specific assert.h like
>
> #ifndef __GCC_ASSERT_H
> #define __GCC_ASSERT_H
>
> #include_next <assert.h>
>
> #if defined __OPTIMIZE__ && defined NDEBUG
> #undef assert
> extern void __gcc_verify (void) __attribute__ ((__const__, 
> __noreturn__));
> #define assert(expr)  ((void) ((expr) ? 0 : (__gcc_verify(), 0)))
> #endif
> #endif

Having implemented exactly the same optimization in another compiler, I 
can safely point out that this isn't a legal transformation as shown. 
(And if the staff patent attorney hadn't gone on maternity leave at 
exactly that time, there's probably be a patent here to worry about 
too.)

assert() is defined by the C99 standard 7.2 p1-2. p1 says that if 
NDEBUG is defined, the expression is not evaluated. That means that you 
would need to ensure that the expression has no side-effects, including 
overflow, FP traps, and other esoterica.

One approach would be to to define some kind of 
__builtin_side_effects_p(x) function that checks an expression for 
side-effects early on in translation without executing it:

#define assert(expr) ((void) (__builtin_side_effects_p(expr) || (expr) 
? 0 : (__gcc_verify(), 0)))

p1 also says that each time <assert.h> is included, assert() is 
redefined according to the current value of NDEBUG. This means that the 
__GCC_ASSERT_H include guard shown here is illegal.

+------------------------------------------------------------+
| Alexander M. Rosenberg           <mailto:alexr@_spies.com> |
| Nobody cares what I say. Remove the underscore to mail me. |



More information about the Gcc-patches mailing list