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:
#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.
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! " ); #endif #ifndef macro2 printf( "Hello! " ); #endif #ifdef macro3 printf( "Hello! " ); #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! " ); #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.
原文:https://www.cs.auckland.ac.nz/references/unix/digital/AQTLTBTE/TITLE.HTM#book-toc