Proper way to turn off debug macros at compile time.

C

chris.fairles

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).
 
E

Eric Sosman

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
 
G

Guest

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).

One thing you should consider in addition to what is already said, is
that ((void) 0) allows you to write

pprint(p1), pprint(p2), pprint(p3);

It is up to you to decide whether you want to allow that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top