wrote On 08/29/06 13:48,:
> So I took a look at assert.h because I knew it uses -DNDEBUG to turn
> off its assert statements but it does some funky stuff that I don't
> quite understand. I made my own def's something like:
>
> #ifdef DEBUG_LEVEL_1
> #define iprint(expr) printf(#expr " = %d\n", expr)
> #else
> #define iprint(expr)
> #endif
>
> #ifdef DEBUG_LEVEL_2
> #define
> #define pprint(expr) printf(#expr " = %p\n", (void *)(expr))
> #else
> #define pprint(expr)
> #endif
>
> But it was suggested to me that I use some do { } while(0) method or
> ((void) 0) instead of just leaving the define's blank. Whats the
> general opinion on this? (I looked in c-faq without much luck, maybe a
> good q to put in less this is implementation specific).
(The line immediately after the second #ifdef is
kinda funky ...)
The only reason I can think of to insert "code that
does nothing" instead of "nothing" is that the former might
silence a compiler warning in some situations. For example,
with DEBUG_LEVEL_1 undefined in a construct like
if (whatever > 0)
do_something();
else
iprint(whatever);
.... at least one widely-used compiler will warn you that
the `else' is empty. (Compilers can warn about whatever
they want, even perfectly legal C.) If the iprint() macro
expanded to `(void)0' or some other kind of no-op, such a
warning might not appear.
On the other hand, some compilers that would otherwise
have been silent might then start whining about "statement
with no effect" or something of the kind. You cannot win
every time!
My own style -- not "better" or "worse" than yours --
is to communicate my intent to the person who will someday
get a flurry of compiler warnings and come browsing through
the code to see what all the fuss is about
:
#ifdef DEBUG_LEVEL_1
#define iprint(x) printf(...etc...)
#else
#define iprint(x) /* nil */
#endif
--