www.delorie.com/gnu/docs/gcc/cpp_29.html   search  
 
Buy the book!


The C Preprocessor

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.9.3 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)  \
{ 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 logical line, so that it resembles the way such 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. However, since it looks like a function call, it minimizes confusion if you can use it like a function call, writing a semicolon afterward, as in SKIP_SPACES (p, lim);

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 { 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. The loop executes exactly once; most compilers generate no extra code for it.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003