📄 cpp.texi
字号:
@exampleif (*p != 0) SKIP_SPACES (p, lim);else @dots{}@end example@noindentThe presence of two statements---the compound statement and a nullstatement---in between the @samp{if} condition and the @samp{else}makes invalid C code.The definition of the macro @samp{SKIP_SPACES} can be altered to solvethis problem, using a @samp{do @dots{} while} statement. Here is how:@example#define SKIP_SPACES (p, limit) \do @{ register char *lim = (limit); \ while (p != lim) @{ \ if (*p++ != ' ') @{ \ p--; break; @}@}@} \while (0)@end exampleNow @samp{SKIP_SPACES (p, lim);} expands into@exampledo @{@dots{}@} while (0);@end example@noindentwhich is one statement.@node Side Effects, Self-Reference, Swallow Semicolon, Macro Pitfalls@subsubsection Duplication of Side Effects@cindex side effects (in macro arguments)@cindex unsafe macrosMany C programs define a macro @samp{min}, for ``minimum'', like this:@example#define min(X, Y) ((X) < (Y) ? (X) : (Y))@end exampleWhen you use this macro with an argument containing a side effect,as shown here,@examplenext = min (x + y, foo (z));@end example@noindentit expands as follows:@examplenext = ((x + y) < (foo (z)) ? (x + y) : (foo (z)));@end example@noindentwhere @samp{x + y} has been substituted for @samp{X} and @samp{foo (z)}for @samp{Y}.The function @samp{foo} is used only once in the statement as it appearsin the program, but the expression @samp{foo (z)} has been substitutedtwice into the macro expansion. As a result, @samp{foo} might be calledtwo times when the statement is executed. If it has side effects orif it takes a long time to compute, the results might not be what youintended. We say that @samp{min} is an @dfn{unsafe} macro.The best solution to this problem is to define @samp{min} in a way thatcomputes the value of @samp{foo (z)} only once. The C language offers nostandard way to do this, but it can be done with GNU C extensions asfollows:@example#define min(X, Y) \(@{ typeof (X) __x = (X), __y = (Y); \ (__x < __y) ? __x : __y; @})@end exampleIf you do not wish to use GNU C extensions, the only solution is to becareful when @emph{using} the macro @samp{min}. For example, you cancalculate the value of @samp{foo (z)}, save it in a variable, and use thatvariable in @samp{min}:@example#define min(X, Y) ((X) < (Y) ? (X) : (Y))@dots{}@{ int tem = foo (z); next = min (x + y, tem);@}@end example@noindent(where we assume that @samp{foo} returns type @samp{int}).@node Self-Reference, Argument Prescan, Side Effects, Macro Pitfalls@subsubsection Self-Referential Macros@cindex self-referenceA @dfn{self-referential} macro is one whose name appears in its definition.A special feature of ANSI Standard C is that the self-reference is notconsidered a macro call. It is passed into the preprocessor outputunchanged.Let's consider an example:@example#define foo (4 + foo)@end example@noindentwhere @samp{foo} is also a variable in your program.Following the ordinary rules, each reference to @samp{foo} will expand into@samp{(4 + foo)}; then this will be rescanned and will expand into @samp{(4+ (4 + foo))}; and so on until it causes a fatal error (memory full) in thepreprocessor.However, the special rule about self-reference cuts this process shortafter one step, at @samp{(4 + foo)}. Therefore, this macro definitionhas the possibly useful effect of causing the program to add 4 tothe value of @samp{foo} wherever @samp{foo} is referred to.In most cases, it is a bad idea to take advantage of this feature. Aperson reading the program who sees that @samp{foo} is a variable willnot expect that it is a macro as well. The reader will come across theidentifier @samp{foo} in the program and think its value should be thatof the variable @samp{foo}, whereas in fact the value is four greater.The special rule for self-reference applies also to @dfn{indirect}self-reference. This is the case where a macro @var{x} expands to use amacro @samp{y}, and the expansion of @samp{y} refers to the macro@samp{x}. The resulting reference to @samp{x} comes indirectly from theexpansion of @samp{x}, so it is a self-reference and is not furtherexpanded. Thus, after@example#define x (4 + y)#define y (2 * x)@end example@noindent@samp{x} would expand into @samp{(4 + (2 * x))}. Clear?But suppose @samp{y} is used elsewhere, not from the definition of @samp{x}.Then the use of @samp{x} in the expansion of @samp{y} is not a self-referencebecause @samp{x} is not ``in progress''. So it does expand. However,the expansion of @samp{x} contains a reference to @samp{y}, and thatis an indirect self-reference now because @samp{y} is ``in progress''.The result is that @samp{y} expands to @samp{(2 * (4 + y))}.It is not clear that this behavior would ever be useful, but it is specifiedby the ANSI C standard, so you may need to understand it.@node Argument Prescan, Cascaded Macros, Self-Reference, Macro Pitfalls@subsubsection Separate Expansion of Macro ArgumentsWe have explained that the expansion of a macro, including the substitutedactual arguments, is scanned over again for macro calls to be expanded.What really happens is more subtle: first each actual argument text is scannedseparately for macro calls. Then the results of this are substituted intothe macro body to produce the macro expansion, and the macro expansionis scanned again for macros to expand.The result is that the actual arguments are scanned @emph{twice} to expandmacro calls in them.Most of the time, this has no effect. If the actual argument containedany macro calls, they are expanded during the first scan. The resulttherefore contains no macro calls, so the second scan does not change it.If the actual argument were substituted as given, with no prescan,the single remaining scan would find the same macro calls and producethe same results.You might expect the double scan to change the results when aself-referential macro is used in an actual argument of another macro(@pxref{Self-Reference}): the self-referential macro would be expanded oncein the first scan, and a second time in the second scan. But this is notwhat happens. The self-references that do not expand in the first scan aremarked so that they will not expand in the second scan either.The prescan is not done when an argument is stringified or concatenated.Thus,@example#define str(s) #s#define foo 4str (foo)@end example@noindentexpands to @samp{"foo"}. Once more, prescan has been prevented fromhaving any noticeable effect.More precisely, stringification and concatenation use the argument aswritten, in un-prescanned form. The same actual argument would be used inprescanned form if it is substituted elsewhere without stringification orconcatenation.@example#define str(s) #s lose(s)#define foo 4str (foo)@end exampleexpands to @samp{"foo" lose(4)}.You might now ask, ``Why mention the prescan, if it makes no difference?And why not skip it and make the preprocessor faster?'' The answer isthat the prescan does make a difference in three special cases:@itemize @bullet@itemNested calls to a macro.@itemMacros that call other macros that stringify or concatenate.@itemMacros whose expansions contain unshielded commas.@end itemizeWe say that @dfn{nested} calls to a macro occur when a macro's actualargument contains a call to that very macro. For example, if @samp{f}is a macro that expects one argument, @samp{f (f (1))} is a nestedpair of calls to @samp{f}. The desired expansion is made byexpanding @samp{f (1)} and substituting that into the definition of@samp{f}. The prescan causes the expected result to happen.Without the prescan, @samp{f (1)} itself would be substituted asan actual argument, and the inner use of @samp{f} would appearduring the main scan as an indirect self-reference and would notbe expanded. Here, the prescan cancels an undesirable side effect(in the medical, not computational, sense of the term) of the specialrule for self-referential macros.But prescan causes trouble in certain other cases of nested macro calls.Here is an example:@example#define foo a,b#define bar(x) lose(x)#define lose(x) (1 + (x))bar(foo)@end example@noindentWe would like @samp{bar(foo)} to turn into @samp{(1 + (foo))}, whichwould then turn into @samp{(1 + (a,b))}. But instead, @samp{bar(foo)}expands into @samp{lose(a,b)}, and you get an error because @code{lose}requires a single argument. In this case, the problem is easily solvedby the same parentheses that ought to be used to prevent misnesting ofarithmetic operations:@example#define foo (a,b)#define bar(x) lose((x))@end exampleThe problem is more serious when the operands of the macro are notexpressions; for example, when they are statements. Then parenthesesare unacceptable because they would make for invalid C code:@example#define foo @{ int a, b; @dots{} @}@end example@noindentIn GNU C you can shield the commas using the @samp{(@{@dots{}@})}construct which turns a compound statement into an expression:@example#define foo (@{ int a, b; @dots{} @})@end exampleOr you can rewrite the macro definition to avoid such commas:@example#define foo @{ int a; int b; @dots{} @}@end exampleThere is also one case where prescan is useful. It is possibleto use prescan to expand an argument and then stringify it---if you usetwo levels of macros. Let's add a new macro @samp{xstr} to theexample shown above:@example#define xstr(s) str(s)#define str(s) #s#define foo 4xstr (foo)@end exampleThis expands into @samp{"4"}, not @samp{"foo"}. The reason for thedifference is that the argument of @samp{xstr} is expanded at prescan(because @samp{xstr} does not specify stringification or concatenation ofthe argument). The result of prescan then forms the actual argument for@samp{str}. @samp{str} uses its argument without prescan because itperforms stringification; but it cannot prevent or undo the prescanningalready done by @samp{xstr}.@node Cascaded Macros, Newlines in Args, Argument Prescan, Macro Pitfalls@subsubsection Cascaded Use of Macros@cindex cascaded macros@cindex macro body uses macroA @dfn{cascade} of macros is when one macro's body contains a referenceto another macro. This is very common practice. For example,@example#define BUFSIZE 1020#define TABLESIZE BUFSIZE@end exampleThis is not at all the same as defining @samp{TABLESIZE} to be @samp{1020}.The @samp{#define} for @samp{TABLESIZE} uses exactly the body youspecify---in this case, @samp{BUFSIZE}---and does not check to see whetherit too is the name of a macro.It's only when you @emph{use} @samp{TABLESIZE} that the result of its expansionis checked for more macro names.This makes a difference if you change the definition of @samp{BUFSIZE}at some point in the source file. @samp{TABLESIZE}, defined as shown,will always expand using the definition of @samp{BUFSIZE} that iscurrently in effect:@example#define BUFSIZE 1020#define TABLESIZE BUFSIZE#undef BUFSIZE#define BUFSIZE 37@end example@noindentNow @samp{TABLESIZE} expands (in two stages) to @samp{37}.@node Newlines in Args,, Cascaded Macros, Macro Pitfalls@subsection Newlines in Macro ArgumentsTraditional macro processing carries forward all newlines in macroarguments into the expansion of the macro. This means that, if some ofthe arguments are substituted more than once, or not at all, or out oforder, newlines can be duplicated, lost, or moved around within theexpansion. If the expansion consists of multiple statements, then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -