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:
#if
#ifdef
#ifndef
Optionally, an alternative block of text can be set aside with one of two directives:
#else
#elif
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.
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.
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.
The #ifndef
directive has the following syntax:
#ifndef identifier newline
This directive checks to see if the identifier is not currently defined.
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.
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.
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
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.