Versions Compared

Key

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

...

which is certainly not what the programmer intended.

Noncompliant Code Example

This noncompliant code example also contains multiple, unbound statements.

Code Block
bgColor#ffcccc

/*
 * Swaps two values.
 */
#define SWAP(x,y) { int tmp; 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

if (x > y)
  SWAP(x,y);          /* Branch 1 */
else  
  do_something();     /* Branch 2 */
{code:bgColor=#ffcccc}

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

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

The problem is the semi-colon ';' following the block. 

h2. Compliant Solution

...



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

...


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

...

Wiki Markup
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "NMP Pre-processor Directions"
[Linux Kernel Newbies FAQ|http://kernelnewbies.org/FAQ] [FAQ/DoWhile0|http://kernelnewbies.org/FAQ/DoWhile0]

...

      01. Preprocessor (PRE)      PRE11-C. Do not conclude a single statement macro definition with a semicolon