GNU Info

Info Node: (cpp-300.info)Swallowing the Semicolon

(cpp-300.info)Swallowing the Semicolon


Next: Duplication of Side Effects Prev: Operator Precedence Problems Up: Macro Pitfalls
Enter node , (file) or (file)node

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.


automatically generated by info2www version 1.2.2.9