8.2 Conditional Compilation (#if, #ifdef, #ifndef, #else, #elif, #endif, and defined)

Six directives are available to control conditional compilation. They delimit blocks of program text that are compiled only if a specified condition is true. These directives can be nested. The program text within the blocks is arbitrary and may consist of preprocessor directives, C statements, and so on. The beginning of the block of program text is marked by one of three directives:

Optionally, an alternative block of text can be set aside with one of two directives:

The end of the block or alternative block is marked by the #endif directive.

If the condition checked by #if , #ifdef , or #ifndef is true (nonzero), then all lines between the matching #else (or #elif ) and an #endif directive, if present, are ignored.

If the condition is false (0), then the lines between the #if , #ifdef , or #ifndef and an #else , #elif , or #endif directive are ignored.

8.2.1 The #if Directive

The #if directive has the following syntax:

#if constant-expression newline

This directive checks whether the constant-expression is true (nonzero). The operand must be a constant integer expression that does not contain any increment (++), decrement (- -), sizeof , pointer (*), address (&), and cast operators.

Identifiers in the constant expression either are or are not macro names. There are no keywords, enumeration constants, and so on. The constant expression can also include the defined preprocessing operator (see Section 8.2.7).

The constant expression in an #if directive is subject to text replacement and can contain references to identifiers defined in previous #define directives. The replacement occurs before the expression is evaluated. Each preprocessing token that remains after all macro replacements have occurred is in the lexical form of a token.

If an identifier used in the expression is not currently defined, the compiler treats the identifier as though it were the constant zero.

8.2.2 The #ifdef Directive

The #ifdef directive has the following syntax:

#ifdef identifier newline

This directive checks whether the identifier is currently defined. Identifiers can be defined by a #define directive or on the command line. If such identifiers have not been subsequently undefined, they are considered currently defined.

8.2.3 The #ifndef Directive

The #ifndef directive has the following syntax:

#ifndef identifier newline

This directive checks to see if the identifier is not currently defined.

8.2.4 The #else Directive

The #else directive has the following syntax:

#else newline

This directive delimits alternative source text to be compiled if the condition tested for in the corresponding #if , #ifdef , or #ifndef directive is false. An #else directive is optional.

8.2.5 The #elif Directive

The #elif directive has the following syntax:

#elif constant-expression newline

The #elif directive performs a task similar to the combined use of the else-if statements in C. This directive delimits alternative source lines to be compiled if the constant expression in the corresponding #if , #ifdef , #ifndef , or another #elif directive is false and if the additional constant expression presented in the #elif line is true. An #elif directive is optional.

8.2.6 The #endif Directive

The #endif directive has the following syntax:

#endif newline

This directive ends the scope of the #if , #ifdef , #ifndef , #else , or #elif directive.

The number of necessary #endif directives changes according to whether the elif or #else directive is used. Consider the following equivalent examples:

#if true                             #if true
.                                    .
.                                    .
.                                    .
#elif true                           .
.                                    #else
.                                    #if false
.                                    .
#endif                               .
                                     .
                                     #endif
                                     #endif

8.2.7 The defined Operator

Another way to verify that a macro is defined is to use the defined unary operator. The defined operator has one of the following forms:

defined name
defined (name)

An expression of this form evaluates to 1 if name is defined and to 0 if it is not.

The defined operator is especially useful for checking many macros with just a single use of the #if directive. In this way, you can check for macro definitions in one concise line without having to use many #ifdef or #ifndef directives.

For example, consider the following macro checks:

#ifdef  macro1
printf( "Hello!\n" );
#endif

#ifndef  macro2
printf( "Hello!\n" );
#endif

#ifdef  macro3
printf( "Hello!\n" );
#endif

Another use of the defined operator is in a single #if directive to perform similar macro checks:

#if  defined (macro1)  || !defined (macro2) || defined (macro3)
printf( "Hello!\n" );
#endif

Note that defined operators can be combined in any logical expression using the C logical operators. However, defined can only be used in the evaluated expression of an #if or #elif preprocessor directive.


Previous Page | Next Page | Table of Contents | Index