Стандарт языка Си С99 TC (1113411), страница 32
Текст из файла (страница 32)
) replacement-list new-line# define identifier lparen identifier-list , ... )replacement-list new-line# undefidentifier new-line# linepp-tokens new-line# errorpp-tokensopt new-line# pragma pp-tokensopt new-line#new-linetext-line:pp-tokensopt new-linenon-directive:pp-tokens new-linelparen:a ( character not immediately preceded by white-spacereplacement-list:pp-tokensoptpp-tokens:preprocessing-tokenpp-tokens preprocessing-tokennew-line:the new-line characterDescription2A preprocessing directive consists of a sequence of preprocessing tokens that satisfies thefollowing constraints: The first token in the sequence is a # preprocessing token that (atthe start of translation phase 4) is either the first character in the source file (optionallyafter white space containing no new-line characters) or that follows white spacecontaining at least one new-line character. The last token in the sequence is the first newline character that follows the first token in the sequence.143) A new-line character endsthe preprocessing directive even if it occurs within what would otherwise be an143) Thus, preprocessing directives are commonly called ‘‘lines’’.
These ‘‘lines’’ have no other syntacticsignificance, as all white space is equivalent except in certain situations during preprocessing (see the# character string literal creation operator in 6.10.3.2, for example).146Language§6.10WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3invocation of a function-like macro.3A text line shall not begin with a # preprocessing token. A non-directive shall not beginwith any of the directive names appearing in the syntax.4When in a group that is skipped (6.10.1), the directive syntax is relaxed to allow anysequence of preprocessing tokens to occur between the directive name and the followingnew-line character.Constraints5The only white-space characters that shall appear between preprocessing tokens within apreprocessing directive (from just after the introducing # preprocessing token throughjust before the terminating new-line character) are space and horizontal-tab (includingspaces that have replaced comments or possibly other white-space characters intranslation phase 3).Semantics6The implementation can process and skip sections of source files conditionally, includeother source files, and replace macros.
These capabilities are called preprocessing,because conceptually they occur before translation of the resulting translation unit.7The preprocessing tokens within a preprocessing directive are not subject to macroexpansion unless otherwise stated.8EXAMPLEIn:#define EMPTYEMPTY # include <file.h>the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does notbegin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has beenreplaced.6.10.1 Conditional inclusionConstraints1The expression that controls conditional inclusion shall be an integer constant expressionexcept that: it shall not contain a cast; identifiers (including those lexically identical tokeywords) are interpreted as described below;144) and it may contain unary operatorexpressions of the form144) Because the controlling constant expression is evaluated during translation phase 4, all identifierseither are or are not macro names — there simply are no keywords, enumeration constants, etc.§6.10.1Language147ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N1256defined identifierordefined ( identifier )which evaluate to 1 if the identifier is currently defined as a macro name (that is, if it ispredefined or if it has been the subject of a #define preprocessing directive without anintervening #undef directive with the same subject identifier), 0 if it is not.2Each preprocessing token that remains (in the list of preprocessing tokens that willbecome the controlling expression) after all macro replacements have occurred shall be inthe lexical form of a token (6.4).Semantics3Preprocessing directives of the forms# ifconstant-expression new-line groupopt# elif constant-expression new-line groupoptcheck whether the controlling constant expression evaluates to nonzero.4Prior to evaluation, macro invocations in the list of preprocessing tokens that will becomethe controlling constant expression are replaced (except for those macro names modifiedby the defined unary operator), just as in normal text.
If the token defined isgenerated as a result of this replacement process or use of the defined unary operatordoes not match one of the two specified forms prior to macro replacement, the behavior isundefined. After all replacements due to macro expansion and the defined unaryoperator have been performed, all remaining identifiers (including those lexicallyidentical to keywords) are replaced with the pp-number 0, and then each preprocessingtoken is converted into a token. The resulting tokens compose the controlling constantexpression which is evaluated according to the rules of 6.6. For the purposes of thistoken conversion and evaluation, all signed integer types and all unsigned integer typesact as if they have the same representation as, respectively, the types intmax_t anduintmax_t defined in the header <stdint.h>.145) This includes interpretingcharacter constants, which may involve converting escape sequences into executioncharacter set members.
Whether the numeric value for these character constants matchesthe value obtained when an identical character constant occurs in an expression (otherthan within a #if or #elif directive) is implementation-defined.146) Also, whether asingle-character character constant may have a negative value is implementation-defined.5Preprocessing directives of the forms145) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 0xFFFF, the constant0x8000 is signed and positive within a #if expression even though it would be unsigned intranslation phase 7.148Language§6.10.1WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3# ifdef identifier new-line groupopt# ifndef identifier new-line groupoptcheck whether the identifier is or is not currently defined as a macro name.
Theirconditions are equivalent to #if defined identifier and #if !defined identifierrespectively.6Each directive’s condition is checked in order. If it evaluates to false (zero), the groupthat it controls is skipped: directives are processed only through the name that determinesthe directive in order to keep track of the level of nested conditionals; the rest of thedirectives’ preprocessing tokens are ignored, as are the other preprocessing tokens in thegroup. Only the first group whose control condition evaluates to true (nonzero) isprocessed. If none of the conditions evaluates to true, and there is a #else directive, thegroup controlled by the #else is processed; lacking a #else directive, all the groupsuntil the #endif are skipped.147)Forward references: macro replacement (6.10.3), source file inclusion (6.10.2), largestinteger types (7.18.1.5).6.10.2 Source file inclusionConstraints1A #include directive shall identify a header or source file that can be processed by theimplementation.Semantics2A preprocessing directive of the form# include <h-char-sequence> new-linesearches a sequence of implementation-defined places for a header identified uniquely bythe specified sequence between the < and > delimiters, and causes the replacement of thatdirective by the entire contents of the header.
How the places are specified or the headeridentified is implementation-defined.3A preprocessing directive of the form146) Thus, the constant expression in the following #if directive and if statement is not guaranteed toevaluate to the same value in these two contexts.#if 'z' - 'a' == 25if ('z' - 'a' == 25)147) As indicated by the syntax, a preprocessing token shall not follow a #else or #endif directivebefore the terminating new-line character.
However, comments may appear anywhere in a source file,including within a preprocessing directive.§6.10.2Language149ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N1256# include "q-char-sequence" new-linecauses the replacement of that directive by the entire contents of the source file identifiedby the specified sequence between the " delimiters.
The named source file is searchedfor in an implementation-defined manner. If this search is not supported, or if the searchfails, the directive is reprocessed as if it read# include <h-char-sequence> new-linewith the identical contained sequence (including > characters, if any) from the originaldirective.4A preprocessing directive of the form# include pp-tokens new-line(that does not match one of the two previous forms) is permitted.
The preprocessingtokens after include in the directive are processed just as in normal text. (Eachidentifier currently defined as a macro name is replaced by its replacement list ofpreprocessing tokens.) The directive resulting after all replacements shall match one ofthe two previous forms.148) The method by which a sequence of preprocessing tokensbetween a < and a > preprocessing token pair or a pair of " characters is combined into asingle header name preprocessing token is implementation-defined.5The implementation shall provide unique mappings for sequences consisting of one ormore nondigits or digits (6.4.2.1) followed by a period (.) and a single nondigit. Thefirst character shall not be a digit. The implementation may ignore distinctions ofalphabetical case and restrict the mapping to eight significant characters before theperiod.6A #include preprocessing directive may appear in a source file that has been readbecause of a #include directive in another file, up to an implementation-definednesting limit (see 5.2.4.1).7EXAMPLE 1The most common uses of #include preprocessing directives are as in the following:#include <stdio.h>#include "myprog.h"8EXAMPLE 2This illustrates macro-replaced #include directives:148) Note that adjacent string literals are not concatenated into a single string literal (see the translationphases in 5.1.1.2); thus, an expansion that results in two string literals is an invalid directive.150Language§6.10.2WG14/N1256Committee Draft — Septermber 7, 2007#if VERSION == 1#define INCFILE#elif VERSION == 2#define INCFILE#else#define INCFILE#endif#include INCFILEISO/IEC 9899:TC3"vers1.h""vers2.h"// and so on"versN.h"Forward references: macro replacement (6.10.3).6.10.3 Macro replacementConstraints1Two replacement lists are identical if and only if the preprocessing tokens in both havethe same number, ordering, spelling, and white-space separation, where all white-spaceseparations are considered identical.2An identifier currently defined as an object-like macro shall not be redefined by another#define preprocessing directive unless the second definition is an object-like macrodefinition and the two replacement lists are identical.