Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example contains multiple, unbound statements.

Code Block
bgColor#FFcccc
langc#ffcccc
/*
 * Swaps two values.
 * Requires tmp variable to be defined.
 */
#define SWAP(x, y) \
  tmp = x; \
  x = y; \
  y = tmp

This macro will expand correctly in a normal sequence of statements, but not as the then-clause in an if statement:

Code Block
bgColor#FFcccc
langc#ffcccc
int x, y, z, tmp;
if (z == 0)
  SWAP( x, y);

This will expand to

Code Block
bgColor#FFcccc
lang#ffccccc
int x, y, z, tmp;
if (z == 0)
  tmp = x;
x = y;
y = tmp;

...

This noncompliant code example inadequately bounds multiple statements.

Code Block
bgColor#FFcccc
lang#ffccccc
/*
 * Swaps two values.
 * Requires tmp variable to be defined.
 */
#define SWAP(x,y) { tmp=x; x=y; y=tmp; }

This macro fails to expand correctly in some case such as the following example which is meant to be an if-statement with two branches:

Code Block
bgColor#FFcccc
langc#ffcccc
if (x > y)
  SWAP(x,y);          /* Branch 1 */
else  
  do_something();     /* Branch 2 */

Following macro expansion, however, this code is interpreted as an if-statement with only one branch:

Code Block
bgColor#FFcccc
langc#ffcccc
if (x > y) { /* Single-branch if-statement!!! */

  tmp = x;   /* The one and only branch consists */
  x = y;     /* of the block. */
  y = tmp;
}
;            /* empty statement */
else         /* ERROR!!! "parse error before else" */
  do_something();

...

Wrapping the macro inside a do-while loop mitigates the problem.

Code Block
bgColor#ccccFF
langc#ccccff
/*
 * Swaps two values.
 * Requires tmp variable to be defined.
 */
#define SWAP(x, y) \
  do { \
    tmp = x; \
    x = y; \
    y = tmp; } \
  while (0)

...