cpp.info: Swallow Semicolon
Go forward to Side Effects
Go backward to Macro Parentheses
Go up to Macro Pitfalls
Go to the top op cpp
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.
Created Wed Sep 1 16:42:06 2004 on bee with info_to_html version 0.9.6.