#ifdef DEBUG versus #if DEBUG
It is unclear to me when using compiler directives which of the below two code snippets is correct/preferred and why. It seems that most developers and Open Source projects I've seen use the first but I have seen the second used frequently as well.
#ifdef DEBUG
[self doSomethingOnlyWhenDebugging];
#endif
VERSUS
#if DEBUG
[self doSomethingOnlyWhenDebugging];
#endif
Which of the above code snippets is preferable for running code only while debugging and why? My guess is that the first will run if DEBUG is defined as TRUE or FALSE where the second will run only if DEBUG is defined and set to TRUE. Is that correct?
You are correct. #if DEBUG
will not evaluate if DEBUG
is defined as 0
.
As for when to use each, you can stick to using #ifdef
for anything where you only need to add code if the preprocessor definition is present, such as adding debug logging. If you need to inspect the value and go down different compilation paths, then I would use a 0
or 1
. A good example of that is TARGET_IPHONE_SIMULATOR
, which is always defined for an iOS project, but only 1
if you’re compiling for the simulator.
As I know, the finest choice is:
#ifndef DEBUG
NSLog(@"-1");
#elif DEBUG == 0
NSLog(@"0");
#else
NSLog(@"%d", DEBUG);
#endif
then, you will know #ifndef DEBUG
is preferred above all others.
There is a simpler choice:
#if DEBUG == 0 // DEBUG is not defined or defined to be 0
// do sth
#else
// do sth
#endif
However, if -Wundef compiler flag is on, there might be a warning with #if DEBUG == 0
.
You need to look at the code where DEBUG gets defined or not defined, and write your code accordingly. With DEBUG, you will find that it is either not defined, or defined with a value of 1. So either #if
DEBUG or #ifdef
DEBUG will work.
For #define
's that are under your control, I recommend that you always define them, either with a value of 0 or 1. You can then use #if
to check for the value, but you can also use them directly in an ordinary if statement or in an expression, which may make your code more readable. And since it is always defined, you can use "Jump To Definition" in Xcode to go to the place where it is defined and check how and why it is set. If instead you either #define
or not #define
the value, and it is not defined, then Xcode will have no idea where in your source code it is not defined. It also gives you a chance to look for misspelled uses. If "Jump to Definition" doesn't work, then you know you have spelled it wrong.
BTW Within an #if
directive, any macro that is not defined is replaced by 0. So #if
DEBUG will work if DEBUG is not defined, or if DEBUG is defined as 0, and it will not compile if DEBUG is defined as nothing - which will tell you what is wrong so you can fix it. From that point of view, using #if
is better unless it doesn't compile.