00001 /* assert.h
00002 Copyright (C) 2001, 2003 Free Software Foundation, Inc.
00003 Written by Stephane Carrez (stcarrez@nerim.fr)
00004
00005 This f
Almost...
Consider: assert( a == 0 );
This is expanded to
(void)((a == 0) || (__assert (#a == 0, __FILE__, __LINE__),0))
If you have the expression (x || y)
- In this case both x and y evaluate as bools, so if 'a' evals to 0, the definition of || says to try the next bool in line, ie 'y'
So - if your assertion is false, (__assert (#a == 0, __FILE__, __LINE__),0)
gets evaluated, which means __assert()
gets called.
Why the (__assert(), 0) ?? __assert is a function defined as void __assert()
- well ... most of the time. see http://www.opensource.apple.com/source/Libc/Libc-825.26/include/assert.h for one set of assert() macros - note that all of them end up calling a function ...
The comma operator lets you do two things in the same statement, ie i++, j++
- but remember an expression has to evaluate to some value - in this case to the "0" - so the entire statement evaluates to (void)(0 || 0)
which is a valid expression. As a side effect, your expression is evaluated and possibly a function gets called.
Note in (void)(0 || 0)
the first 0 is from your failed assertion. This may be created at compile time if your assertion evaluates to something the compiler can create as a constant, or an expression that gets evaluated, ie (void)((a == 0) || 0)
note the comma ",0" is for really pedantic compilers - I usually don't see it. But the (a || __assert())
is very common. You could write the macro as
#define assert( x ) { if( ! (x)) __assert(.....); }