home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 4
/
FreshFish_May-June1994.bin
/
gnu
/
info
/
cpp.info-2
(
.txt
)
< prev
next >
Wrap
GNU Info File
|
1994-02-20
|
50KB
|
925 lines
This is Info file cpp.info, produced by Makeinfo-1.55 from the input
file cpp.texi.
This file documents the GNU C Preprocessor.
Copyright 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.
Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.
File: cpp.info, Node: Swallow Semicolon, Next: Side Effects, Prev: Macro Parentheses, Up: Macro Pitfalls
Swallowing the Semicolon
........................
Often it is desirable to define a macro that expands into a compound
statement. Consider, for example, the following macro, that advances a
pointer (the argument `p' says where to find it) across whitespace
characters:
#define SKIP_SPACES (p, limit) \
{ register char *lim = (limit); \
while (p != lim) { \
if (*p++ != ' ') { \
p--; break; }}}
Here Backslash-Newline is used to split the macro definition, which must
be a single line, so that it resembles the way such C code would be
laid out if not part of a macro definition.
A call to this macro might be `SKIP_SPACES (p, lim)'. Strictly
speaking, the call expands to a compound statement, which is a complete
statement with no need for a semicolon to end it. But it looks like a
function call. So it minimizes confusion if you can use it like a
function call, writing a semicolon afterward, as in `SKIP_SPACES (p,
lim);'
But this can cause trouble before `else' statements, because the
semicolon is actually a null statement. Suppose you write
if (*p != 0)
SKIP_SPACES (p, lim);
else ...
The presence of two statements--the compound statement and a null
statement--in between the `if' condition and the `else' makes invalid C
code.
The definition of the macro `SKIP_SPACES' can be altered to solve
this problem, using a `do ... while' statement. Here is how:
#define SKIP_SPACES (p, limit) \
do { register char *lim = (limit); \
while (p != lim) { \
if (*p++ != ' ') { \
p--; break; }}} \
while (0)
Now `SKIP_SPACES (p, lim);' expands into
do {...} while (0);
which is one statement.
File: cpp.info, Node: Side Effects, Next: Self-Reference, Prev: Swallow Semicolon, Up: Macro Pitfalls
Duplication of Side Effects
...........................
Many C programs define a macro `min', for "minimum", like this:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
When you use this macro with an argument containing a side effect,
as shown here,
next = min (x + y, foo (z));
it expands as follows:
next = ((x + y) < (foo (z)) ? (x + y) : (foo (z)));
where `x + y' has been substituted for `X' and `foo (z)' for `Y'.
The function `foo' is used only once in the statement as it appears
in the program, but the expression `foo (z)' has been substituted twice
into the macro expansion. As a result, `foo' might be called two times
when the statement is executed. If it has side effects or if it takes
a long time to compute, the results might not be what you intended. We
say that `min' is an "unsafe" macro.
The best solution to this problem is to define `min' in a way that
computes the value of `foo (z)' only once. The C language offers no
standard way to do this, but it can be done with GNU C extensions as
follows:
#define min(X, Y) \
({ typeof (X) __x = (X), __y = (Y); \
(__x < __y) ? __x : __y; })
If you do not wish to use GNU C extensions, the only solution is to
be careful when *using* the macro `min'. For example, you can
calculate the value of `foo (z)', save it in a variable, and use that
variable in `min':
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
...
{
int tem = foo (z);
next = min (x + y, tem);
}
(where we assume that `foo' returns type `int').
File: cpp.info, Node: Self-Reference, Next: Argument Prescan, Prev: Side Effects, Up: Macro Pitfalls
Self-Referential Macros
.......................
A "self-referential" macro is one whose name appears in its
definition. A special feature of ANSI Standard C is that the
self-reference is not considered a macro call. It is passed into the
preprocessor output unchanged.
Let's consider an example:
#define foo (4 + foo)
where `foo' is also a variable in your program.
Following the ordinary rules, each reference to `foo' will expand
into `(4 + foo)'; then this will be rescanned and will expand into `(4
+ (4 + foo))'; and so on until it causes a fatal error (memory full) in
the preprocessor.
However, the special rule about self-reference cuts this process
short after one step, at `(4 + foo)'. Therefore, this macro definition
has the possibly useful effect of causing the program to add 4 to the
value of `foo' wherever `foo' is referred to.
In most cases, it is a bad idea to take advantage of this feature. A
person reading the program who sees that `foo' is a variable will not
expect that it is a macro as well. The reader will come across the
identifier `foo' in the program and think its value should be that of
the variable `foo', whereas in fact the value is four greater.
The special rule for self-reference applies also to "indirect"
self-reference. This is the case where a macro X expands to use a
macro `y', and the expansion of `y' refers to the macro `x'. The
resulting reference to `x' comes indirectly from the expansion of `x',
so it is a self-reference and is not further expanded. Thus, after
#define x (4 + y)
#define y (2 * x)
`x' would expand into `(4 + (2 * x))'. Clear?
But suppose `y' is used elsewhere, not from the definition of `x'.
Then the use of `x' in the expansion of `y' is not a self-reference
because `x' is not "in progress". So it does expand. However, the
expansion of `x' contains a reference to `y', and that is an indirect
self-reference now because `y' is "in progress". The result is that
`y' expands to `(2 * (4 + y))'.
It is not clear that this behavior would ever be useful, but it is
specified by the ANSI C standard, so you may need to understand it.
File: cpp.info, Node: Argument Prescan, Next: Cascaded Macros, Prev: Self-Reference, Up: Macro Pitfalls
Separate Expansion of Macro Arguments
.....................................
We have explained that the expansion of a macro, including the
substituted actual arguments, is scanned over again for macro calls to
be expanded.
What really happens is more subtle: first each actual argument text
is scanned separately for macro calls. Then the results of this are
substituted into the macro body to produce the macro expansion, and the
macro expansion is scanned again for macros to expand.
The result is that the actual arguments are scanned *twice* to expand
macro calls in them.
Most of the time, this has no effect. If the actual argument
contained any macro calls, they are expanded during the first scan.
The result therefore 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 produce the same results.
You might expect the double scan to change the results when a
self-referential macro is used in an actual argument of another macro
(*note Self-Reference::.): the self-referential macro would be expanded
once in the first scan, and a second time in the second scan. But this
is not what happens. The self-references that do not expand in the
first scan are marked so that they will not expand in the second scan
either.
The prescan is not done when an argument is stringified or
concatenated. Thus,
#define str(s