|
|
A preprocessing directive begins with a preprocessing operator, #, on a logical line. Only white spaces are allowed to precede # on the same line. Preprocessing directives can be divided into the following categories:
The preprocessing operators are evaluated left to right, without any defined precedence.
#define identifier token-sequence[opt]where identifier will be replaced with token-sequence wherever identifier appears in regular text.
#define identifier (identifier-list[opt] ) token-sequence[opt]where the macro parameters are contained in the comma-separated identifier-list. The token-sequence following the identifier list determines the behavior of the macro, and is referred to as the replacement list. There can be no space between the identifier and the ``('' character. For example:
#define FLM(a,b) a+bThe replacement-list ``a+b'' determines that the two parameters ``a'' and ``b'' will be added.
FLM(3,2)
#define M1 3When the function-like macro FLM is used, use of the # or ## operators will affect expansion (and the result), as follows:
Definition | Invocation | Result | Expansion ? |
---|---|---|---|
a+b | FLM(M1,2) | 3+2 | Yes, Yes |
#a | FLM(M1,2) | "M1" | No |
a##b | FLM(M1,2) | M12 | No, No |
a+#a | FLM(M1,2) | 3+"M1" | Yes, No |
#undef identifierThere is no effect if the definition does not exist.
#include "filename"causes the entire line to be replaced with the contents of filename. The following directories are searched, in order.
#include <filename>causes the entire line to be replaced with contents of filename. The angle brackets surrounding filename indicate that filename is not searched for in the current directory.
#include preprocessing-tokensThe preprocessing tokens are processed the same way as when they are used in normal text. Any defined macro name is replaced with its replacement list of preprocessing tokens. The preprocessing tokens must expand to match one of the first two forms ( < . . . > or ". . .").
Different segments of a program may be compiled conditionally. Conditional compilation statements must observe the following sequence:
#if
integral-constant-expression
Is true if integral-constant-expression evaluates to non-zero.
If true, tokens following the #if line are included.
The integral-constant-expression following the #if is evaluated by following this sequence of steps:
The following table shows how various types of constant expressions following a #if would be evaluated. Assume that name is not defined.
Constant expression | Step 1 | Step 2 | Step 3 |
---|---|---|---|
!defined(__STDC__) | !1 | !1 | 0 |
3||name | 3||name | 3||0 | 1 |
2 + name | 2 + name | 2 + 0 | 2 |
#ifdef
identifier
Is true if identifier is currently defined by #define or by the -D option to the cc command line.
#ifndef
identifier
Is true if identifier is not currently defined by #define (or has been undefined).
#elif
constant-expression
Indicates alternate if-condition when all preceding if-conditions are false.
#else
Indicates alternate action when no preceding if or elif conditions are true. A comment may follow the else, but a token may not.
#endif
Terminates the current conditional. A comment may follow the endif but a token may not.
#line constant "filename"causes the compiler to believe, for the purposes of error diagnostics and debugging, that the line number of the next source line is equal to constant (which must be a decimal integer) and the current input file is filename (enclosed in double quotes). The quoted filename is optional. constant must be a decimal integer in the range 1 to MAXINT. MAXINT is defined in limits.h.
#assert predicate (token-sequence)associates the token-sequence with the predicate in the assertion name space (separate from the space used for macro definitions). The predicate must be an identifier token.
#assert predicateasserts that predicate exists, but does not associate any token sequence with it.
The compiler provides the following predefined predicates by default:
#assert machine ( i386 ) #assert system ( unix ) #assert cpu ( i386 )Any assertion may be removed by using #unassert, which uses the same syntax as #assert. Using #unassert with no argument deletes all assertions on the predicate; specifying an assertion deletes only that assertion.
An assertion may be tested in a #if statement with the following syntax:
#if #predicate(non-empty token-list)For example, the predefined predicate system can be tested with the following line:
#if #system(unix)which will evaluate true.
The #ident directive is used to help administer version control information.
#ident "version"puts an arbitrary string in the .comment section of the object file. The .comment section is not loaded into memory when the program is executed.
#pragma pp-tokensspecify implementation-defined actions.
#pragma asm [full_optimization|partial_optimization] asm_func #pragma comment comment(argument) #pragma ident version #pragma int_to_unsigned identifier #pragma pack(n) #pragma weak identifier [= identifier2]
For more information on pragmas, see ``Pragmas'' in ``ANSI implementation-defined behavior''.
A preprocessing line consisting of:
#error token-sequencecauses the compiler to produce a diagnostic message containing the token-sequence, and stop.
The following identifiers are predefined as object-like macros:
__LINE__ | The current line number as a decimal constant. |
__FILE__ | A string literal representing the name of the file being compiled. |
__DATE__ | The date of compilation as a string literal in the form "Mmm dd yyyy." |
__TIME__ | The time of compilation, as a string literal in the form "hh:mm:ss." |
__STDC__ | The constant 1 under compilation mode -Xc. Under compilation mode -Xk, it is undefined. Under all other compilation modes, it is constant ``0''. |
__USLC__ | A positive integer constant; its definition signifies a USL C compilation system. |