______________________________________________________________________
16 Preprocessing directives [cpp]
______________________________________________________________________
1 A preprocessing directive consists of a sequence of preprocessing
tokens that begins with a # preprocessing token that is either the
first character in the source file (optionally after white space con
taining no new-line characters) or that follows white space containing
at least one new-line character, and is ended by the next new-line
character.1)
preprocessing-file:
groupopt
group:
group-part
group group-part
group-part:
pp-tokensopt new-line
if-section
control-line
if-section:
if-group elif-groupsopt else-groupopt endif-line
if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
elif-groups:
elif-group
elif-groups elif-group
elif-group:
# elif constant-expression new-line groupopt
else-group:
# else new-line groupopt
endif-line:
# endif new-line
_________________________
1) Thus, preprocessing directives are commonly called "lines." These
"lines" have no other syntactic significance, as all white space is
equivalent except in certain situations during preprocessing (see the
# character string literal creation operator in _cpp.stringize_, for
example).
control-line:
# include pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt ) replacement-list new-line
# undef identifier new-line
# line pp-tokens new-line
# error pp-tokensopt new-line
# pragma pp-tokensopt new-line
# new-line
lparen:
the left-parenthesis character without preceding white-space
replacement-list:
pp-tokensopt
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
new-line:
the new-line character
2 The only white-space characters that shall appear between preprocess
ing tokens within a preprocessing directive (from just after the
introducing # preprocessing token through just before the terminating
new-line character) are space and horizontal-tab (including spaces
that have replaced comments or possibly other white-space characters
in translation phase 3).
3 The implementation can process and skip sections of source files con
ditionally, include other source files, and replace macros. These
capabilities are called preprocessing, because conceptually they occur
before translation of the resulting translation unit.
4 The preprocessing tokens within a preprocessing directive are not sub
ject to macro expansion unless otherwise stated.
16.1 Conditional inclusion [cpp.cond]
1 The expression that controls conditional inclusion shall be an inte
gral constant expression except that: it shall not contain a cast;
identifiers (including those lexically identical to keywords) are
interpreted as described below;2) and it may contain unary operator
expressions of the form
defined identifier
or
defined ( identifier )
which evaluate to 1 if the identifier is currently defined as a macro
name (that is, if it is predefined or if it has been the subject of a
#define preprocessing directive without an intervening #undef direc
tive with the same subject identifier), zero if it is not.
_________________________
2) Because the controlling constant expression is evaluated during
translation phase 4, all identifiers either are or are not macro names
-- there simply are no keywords, enumeration constants, and so on.
2 Each preprocessing token that remains after all macro replacements
have occurred shall be in the lexical form of a token (_lex.token_).
3 Preprocessing directives of the forms
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
check whether the controlling constant expression evaluates to
nonzero.
4 Prior to evaluation, macro invocations in the list of preprocessing
tokens that will become the controlling constant expression are
replaced (except for those macro names modified by the defined unary
operator), just as in normal text. If the token defined is generated
as a result of this replacement process or use of the defined unary
operator does not match one of the two specified forms prior to macro
replacement, the behavior is undefined. After all replacements due to
macro expansion and the defined unary operator have been performed,
all remaining identifiers are replaced with the pp-number 0, and then
each preprocessing token is converted into a token. The resulting
tokens comprise the controlling constant expression which is evaluated
according to the rules of _expr.const_ using arithmetic that has at
least the ranges specified in _lib.support.limits_, except that int
and unsigned int act as if they have the same representation as,
respectively, long and unsigned long. This includes interpreting
character literals, which may involve converting escape sequences into
execution character set members. Whether the numeric value for these
character literals matches the value obtained when an identical char
acter literal occurs in an expression (other than within a #if or
#elif directive) is implementation-defined.3) Also, whether a single-
character character literal may have a negative value is implementa
tion-defined.
5 Preprocessing directives of the forms
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
check whether the identifier is or is not currently defined as a macro
name. Their conditions are equivalent to #if defined identifier and
#if !defined identifier respectively.
6 Each directive's condition is checked in order. If it evaluates to
false (zero), the group that it controls is skipped: directives are
processed only through the name that determines the directive in order
to keep track of the level of nested conditionals; the rest of the
directives' preprocessing tokens are ignored, as are the other prepro
cessing tokens in the group. Only the first group whose control con
dition evaluates to true (nonzero) is processed. If none of the
_________________________
3) Thus, the constant expression in the following #if directive and if
statement is not guaranteed to evaluate to the same value in these two
contexts.
#if 'z' - 'a' == 25
if ('z' - 'a' == 25)
conditions evaluates to true, and there is a #else directive, the
group controlled by the #else is processed; lacking a #else directive,
all the groups until the #endif are skipped.4)
16.2 Source file inclusion [cpp.include]
1 A #include directive shall identify a header or source file that can
be processed by the implementation.
2 A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence between the < and >
delimiters, and causes the replacement of that directive by the entire
contents of the header. How the places are specified or the header
identified is implementation-defined.
3 A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the
source file identified by the specified sequence between the " delim
iters. The named source file is searched for in an implementation-
defined manner. If this search is not supported, or if the search
fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any)
from the original directive.
4 A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The
preprocessing tokens after include in the directive are processed just
as in normal text. (Each identifier currently defined as a macro name
is replaced by its replacement list of prepro>
Transfer interrupted!