Стандарт C++ 98 (1119566), страница 83
Текст из файла (страница 83)
The parameters arespecified by the optional list of identifiers, whose scope extends from their declaration in the identifier listuntil the new-line character that terminates the #define preprocessing directive. Each subsequentinstance of the function-like macro name followed by a ( as the next preprocessing token introduces thesequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation ofthe macro). The replaced sequence of preprocessing tokens is terminated by the matching ) preprocessingtoken, skipping intervening matched pairs of left and right parenthesis preprocessing tokens. Within thesequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considereda normal white-space character.10The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list ofarguments for the function-like macro.
The individual arguments within the list are separated by commapreprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separatearguments. If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undefined. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.16.3.1 Argument substitution1[cpp.subst]After the arguments for the invocation of a function-like macro have been identified, argument substitutiontakes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macroscontained therein have been expanded. Before being substituted, each argument’s preprocessing tokens arecompletely macro replaced as if they formed the rest of the translation unit; no other preprocessing tokensare available.16.3.2 The # operator[cpp.stringize]1Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.2If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both arereplaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument.
Each occurrence of white space between theargument’s preprocessing tokens becomes a single space character in the character string literal. Whitespace before the first preprocessing token and after the last preprocessing token comprising the argument isdeleted. Otherwise, the original spelling of each preprocessing token in the argument is retained in thecharacter string literal, except for special handling for producing the spelling of string literals and characterliterals: a \ character is inserted before each " and \ character of a character literal or string literal (including the delimiting " characters).
If the replacement that results is not a valid character string literal, thebehavior is undefined. The order of evaluation of # and ## operators is unspecified.__________________141) Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see 2.1.1.2, translation phases), they are never scanned for macro names or parameters.142) An alternative token (2.5) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore it isnot possible to define a macro whose name is the same as that of an alternative token.305ISO/IEC 14882:1998(E)16.3.3 The ## operator© ISO/IEC16 Preprocessing directives16.3.3 The ## operator[cpp.concat]1A ## preprocessing token shall not occur at the beginning or at the end of a replacement list for either formof macro definition.2If, in the replacement list, a parameter is immediately preceded or followed by a ## preprocessing token,the parameter is replaced by the corresponding argument’s preprocessing token sequence.3For both object-like and function-like macro invocations, before the replacement list is reexamined formore macro names to replace, each instance of a ## preprocessing token in the replacement list (not froman argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.
If the result is not a valid preprocessing token, the behavior is undefined. The resultingtoken is available for further macro replacement. The order of evaluation of ## operators is unspecified.16.3.4 Rescanning and further replacement[cpp.rescan]1After all parameters in the replacement list have been substituted, the resulting preprocessing tokensequence is rescanned with all subsequent preprocessing tokens of the source file for more macro names toreplace.2If the name of the macro being replaced is found during this scan of the replacement list (not including therest of the source file’s preprocessing tokens), it is not replaced. Further, if any nested replacementsencounter the name of the macro being replaced, it is not replaced.
These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.3The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessingdirective even if it resembles one.16.3.5 Scope of macro definitions[cpp.scope]1A macro definition lasts (independent of block structure) until a corresponding #undef directive isencountered or (if none is encountered) until the end of the translation unit.2A preprocessing directive of the form# undef identifier new-linecauses the specified identifier no longer to be defined as a macro name. It is ignored if the specified identifier is not currently defined as a macro name.3[Note: The simplest use of this facility is to define a “manifest constant,” as in#define TABSIZE 100int table[TABSIZE];4The following defines a function-like macro whose value is the maximum of its arguments.
It has theadvantages of working for any compatible types of the arguments and of generating in-line code without theoverhead of function calling. It has the disadvantages of evaluating one or the other of its arguments a second time (including side effects) and generating more code than a function if invoked several times. It alsocannot have its address taken, as it has none.#define max(a, b) ((a) > (b) ? (a) : (b))The parentheses ensure that the arguments and the resulting expression are bound properly.5To illustrate the rules for redefinition and reexamination, the sequence306© ISO/IECISO/IEC 14882:1998(E)16 Preprocessing directives#define#define#undef#define#define#define#define#define#define#define16.3.5 Scope of macro definitionsxf(a)xxgzhm(a)wt(a)3f(x * (a))2fz[0]g( ~a(w)0,1af(y+1) + f(f(z)) % t(t(g)(0) + t)(1);g(x+(3,4)-w) | h 5) & m(f)^m(m);results inf(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);f(2 * (2+(3,4)-0,1)) | f(2 * ( ~5)) & f(2 * (0,1))^m(0,1);6To illustrate the rules for creating character string literals and concatenating tokens, the sequence#define str(s)# s#define xstr(s)str(s)#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \x ## s, x ## t)#define INCFILE(n) vers ## n /* from previous #include example */#define glue(a, b) a ## b#define xglue(a, b) glue(a, b)#define HIGHLOW"hello"#define LOWLOW ", world"debug(1, 2);fputs(str(strncmp("abc\0d", "abc", ’\4’)= = 0) str(: @\n), s);#include xstr(INCFILE(2).h)glue(HIGH, LOW);xglue(HIGH, LOW)/* this goes away */results inprintf("x" "1" "= %d, x" "2" "= %s", x1, x2);fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) = = 0" ": @\n", s);#include "vers2.h"(after macro replacement, before file access)"hello";"hello" ", world"or, after concatenation of the character string literals,printf("x1= %d, x2= %s", x1, x2);fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) = = 0: @\n", s);#include "vers2.h"(after macro replacement, before file access)"hello";"hello, world"Space around the # and ## tokens in the macro definition is optional.7And finally, to demonstrate the redefinition rules, the following sequence is valid.#define#define#define#defineOBJ_LIKE(1-1)OBJ_LIKE/* white space */ (1-1) /* other */FTN_LIKE(a)( a )FTN_LIKE( a )(/* note the white space */ \a /* other stuff on this line*/ )307ISO/IEC 14882:1998(E)© ISO/IEC16.3.5 Scope of macro definitions16 Preprocessing directivesBut the following redefinitions are invalid:#define#define#define#defineOBJ_LIKEOBJ_LIKEFTN_LIKE(b)FTN_LIKE(b)(0)(1 - 1)( a )( b )/*/*/*/*different token sequence */different white space */different parameter usage */different parameter spelling */—end note]16.4 Line control[cpp.line]1The string literal of a #line directive, if present, shall be a character string literal.2The line number of the current source line is one greater than the number of new-line characters read orintroduced in translation phase 1 (2.1) while processing the source file to the current token.3A preprocessing directive of the form# line digit-sequence new-linecauses the implementation to behave as if the following sequence of source lines begins with a source linethat has a line number as specified by the digit sequence (interpreted as a decimal integer).
If the digitsequence specifies zero or a number greater than 32767, the behavior is undefined.4A preprocessing directive of the form# line digit-sequence "s-char-sequenceopt" new-linesets the line number similarly and changes the presumed name of the source file to be the contents of thecharacter string literal.5A preprocessing directive of the form# line pp-tokens new-line(that does not match one of the two previous forms) is permitted. The preprocessing tokens after line onthe directive are processed just as in normal text (each identifier currently defined as a macro name isreplaced by its replacement list of preprocessing tokens). If the directive resulting after all replacementsdoes not match one of the two previous forms, the behavior is undefined; otherwise, the result is processedas appropriate.16.5 Error directive1[cpp.error]A preprocessing directive of the form# error pp-tokensopt new-linecauses the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens, and renders the program ill-formed.16.6 Pragma directive1[cpp.pragma]A preprocessing directive of the form# pragma pp-tokensopt new-linecauses the implementation to behave in an implementation-defined manner.