Contents|Index|Previous|Next
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; }}}
Note:
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 to use it like a function call, writing
a semicolon afterward, as in the following example.
SKIP_SPACES (p, lim);
But this
can cause trouble before else
statements, because the semicolon is actually a null statement. Suppose
you have the following input.
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.
Use the following input as an example.
#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 one output statement as the following example shows.
do { : : :
} while (0);
Top|Contents|Index|Previous|Next