views:

310

answers:

1

I'd like to code in some preprocessor macros to optionally log some information. For example in the .h

//#define ML_DEBUG(x) (x)  // flip this bit to do the error logging
#define ML_DEBUG(x) (1==1) // flip this bit to silence

in the .m I implement like:

ML_DEBUG(NSLog(@"Class dealloc: %@", [NSString stringWithCString:object_getClassName(self)]));

The code works fine as I have presented it. However I don't think my "do nothing" case is as light weight as it could be. I had expected to write:

//#define ML_DEBUG(x) (x)  // flip this bit to do the error logging
#define ML_DEBUG(x) (;) // flip this bit to silence

Since a lone semicolon is a valid objective-c statement, I expected this would work, but the compiler is telling me:

expected expression before ';' token

My question is: did I choose the most lightweight "do nothing" statement, by using 1==1 or is there a less intensive way to do this. Or maybe my entire approach to temporary debug logging is wrong-headed?

+2  A: 

The simplest thing is an empty definition:

#define ML_DEBUG(x)

This works for most cases, but it does not work with the ternary operator, e.g.:

something ? ML_DEBUG(x) : ML_DEBUG(y);

In order to work for this (admittedly contrived) example, you can do this:

#define ML_DEBUG(x) ((void)0)

It's perfectly valid to cast things to void -- it says to the compiler that you're explicitly ignoring the result of the expression.

It's for this reason that the standard ANSI C macro assert() gets turned into ((void)0) when NDEBUG is defined instead of the empty statement.

Adam Rosenfield