Preprocessor – the #ifdef Directive

Behaviour of the #ifdef directive is the same in both C and C++.

Purpose

The #ifdef directive is one of five preprocessor selection statements allowing selection of alternative sections of code for compilation. The other four selection statements are: #ifndef, #if, #elif, and #else.

Format

#ifdef macro name

valid preprocessor or code statements

#endif or #elif or #else

All preprocessor directives begin with the # symbol. It must be the first character on the line or the first character on the line following optional white space.

Some early compilers flagged an error if # was not the first character on the line.

Spaces or tabs are permitted between the # and ifdef, but not escape characters or other symbols or macros. The preprocessor removes white space and concatenates the # and ifdef together.

The following are valid uses:

#ifdef my_macro
# ifdef my_macro;
# ifdef my_macro
# /* comments are white space */ ifdef my_macro

The following are invalid uses:

// #\ is not a valid preprocessor directive
# \t ifdef my_macro
// #" is not a valid preprocessor directive
# "" ifdef my_macro

Use

If the macro name exists, then the statements following #ifdef until the end of the block (#endif, #else or #elif) are compiled.

If the macro name does not exist, then the statements following #ifdef until the end of the block (#endif, #else or #elif) are skipped (not compiled).

Since the code is conditionally compiled, it is possible the code never gets compiled and, as a consequence, any errors in it are never caught or noticed.

The simplest preprocessor selection block consists of just an #ifdef and a terminating #endif statement.

More complex selection blocks consist of an #ifdef followed by one or more #elif and / or a final #else statement.

Any valid preprocessor statements, including other #ifdef statements, may be part of the code in the selection block. There is no limit on the level of nesting of selection statements.

The following:

#ifdef my_macro

is equivalent to:

#if defined my_macro

In the following example, #ifdef is used to control whether or not a printf is used to print out the function name whenever the function is called. If DEBUG is defined when the code is compiled, then printf("my_function\n") will be part of the compiled code:

int my_function(void)
{
#ifdef DEBUG
printf("my_function\n");
#endif
// function body goes here
return some_value;
}

An alternate way of doing the same thing would be to define a macro:

#ifdef DEBUG
# define TRACE(x) printf(#x"\n")
#else
# define TRACE(x)
#endif

and then use the macro in your code:

int my_function( void )
{
TRACE(my_function);
// function body goes here
return some_value;
}

When the macro DEBUG is defined, then a printf will be compiled into the code. When the macro DEBUG is not defined, then the macro TRACE is replaced with a blank line.