#defines last for the whole file; you can't have local ones like you can for local variables.
``Substitutions are made only for tokens'' means that a substitutable macro name is only recognized when it stands alone. Also, substitution never happens in quoted strings, because it turns out that you usually don't want it to. Strings are generally used for communication with the user, while you want substitutions to happen where you're talking to the compiler.
The point of the ``forever'' example is to demonstrate that the replacement text doesn't have to be a simple number or string constant. You'd use the forever macro like this:
forever { ... }which the preprocessor would expand to
for (;;) { ... }which, as we learned in section 3.5 on page 60, is an infinite loop. (Presumably there's a break; see section 3.7 p. 64.)
Another popular trick is
#define ever ;;so that you can say
for(ever) { ... }But ``preprocessor tricks'' like these tend to get out of hand very quickly; if you use too many of them you're not writing in C any more but rather in your own peculiar dialect, and no one will be able to read your code without understanding all of your ``silly little macros.'' It is best if simple macros expand to simple constants (or expressions).
Macros with arguments are also called ``function-like macros'' because they act almost like miniature functions. There are some important differences, however:
page 90
The correct way to write the square() macro is
#define square(x) ((x) * (x))There are three rules to remember when defining function-like macros:
1 / square(n)might expand to
1 / n * nwhile it should expand to
1 / (n * n)
square(n + 1)might expand to
n + 1 * n + 1while it should expand to
(n + 1) * (n + 1)
square(i++)would result in
i++ * i++(perhaps with some parentheses), but this expression is undefined, because we don't know when the two increments will happen with respect to each other or the multiplication.
#define Square(x) ((x) * (x))
page 90 continued
#undef can be used when you want to give a macro restricted scope, if you can remember to undefine it when you want it to go out of scope. Don't worry about ``[ensuring] that a routine is really a function, not a macro'' or the getchar example.
Also, don't worry about the # and ## operators. These are new ANSI features which aren't needed except in relatively special circumstances.
Read sequentially: prev next up top
This page by Steve Summit // Copyright 1995, 1996 // mail feedback