Game Programming, Etc.

Games, programming, and related topics — by John Giors

Archive for March, 2009

#ifdef vs #if (part 1)

Posted by jgiors on 2009-03-27

In C/C++, it is common to compile some sections of code conditionally, e.g. debugging code, new untested features, cross-platform support, etc. The most common way to conditionally compile code is to use the #define preprocessor directive, then bracket conditionally compiled code with either #ifdef or #if.

Here is a simple #ifdef example:

#define DEBUG_SYSTEMX  //remove this #define to disable (e.g. comment-out this line).
//...
#ifdef DEBUG_SYSTEMX
    //... system x debugging code ...
#endif

And, here is a simple #if example:

#define NEW_FEATURE  1  //change 1 to 0 to disable
//...
#if NEW_FEATURE
    //... new feature code ...
#endif

Both of the above accomplish the same thing (conditional compilation), but they have different implications, e.g. the following will cause a compiler error when DEBUG_SYSTEMX is defined:

#if DEBUG_SYSTEMX  //BAD! #if WHEN IT SHOULD BE #ifdef
    // ... system x debugging code ...
#endif

However, when DEBUG_SYSTEMX is not defined, the code will be compiled out because the preprocessor treats undefined macros as 0 in conditional tests (which just so happens to match expectation).

The following would not work as intended, either:

#ifdef NEW_FEATURE  //BAD! #ifdef WHEN IT SHOULD BE #if
    // ... new feature code ...
#endif

Because NEW_FEATURE is always defined (to either 1 or 0), #ifdef NEW_FEATURE is always true, and the supposedly “conditional” code is always compiled.

So, both cases (#ifdef and #if) have problems if you accidentally use the incorrect test.

Of the two problems, using #ifdef when it should be #if appears to be the more serious error, since it can result in unintended code being included in a build, and no compiler errors or warnings will be generated (unless the conditional code happens to depend on other code which gets compiled out).

However, using #if when it should be #ifdef does the correct thing when the macro is undefined, and it generates a compiler error when the macro is defined (making it simpler to track down).

In this regard, #ifdef appears superior, but there are other considerations which should be taken into account. I’ll delve into some of those considerations (and cases you can’t do much about) in following posts.

Posted in C Preprocessor series, Programming | 2 Comments »