A perfectly useful do-nothing statement

C macros are very useful, but a little taxing for both compiler writers and programmers. They certainly do provoke innovation.

There's an interesting discussion going on about macros over on comp.lang.c. The discussion revolved around declaring a macro destined for expansion in a single statement context.

If the macro has any embedded declarations, it needs its own scope.

#define SWAP(a,b) { T t=a; a=b; b=t; }

The code block encased in braces is not suitable for expansion in a single statement context. It can interfere with if()..else statements:

if(C)
  SWAP(x,y);
else
  NOP();

becomes

if(C)
  { T t=x; x=y; y=t; };
else                      //problem
  NOP();

The solution described is to encase the block in a single statement that does nothing to change the execution:

#define SWAP(a,b) do { T t=a; a=b; b=t; } while (0)

And, of course, we ran a quick check with our compilers to ensure that we got the required result:

0005 0000                            typedef char T;

0007                                 #define SWAP(a,b) do { T t=a; a=b; b=t; } while (0)

0040 0041 0042                       char C,x,y;

                                     void main (void)
                                      {

0100 3D 40        TST    $40           if (C)
0102 27 0A        BEQ    $010E           SWAP(x,y);
0104 00BF  
0104 4E 41 BF     MOV    $41,$BF
0107 4E 42 41     MOV    $42,$41
010A 4E BF 42     MOV    $BF,$42
010D 81           RTS                  else
010E 9D           NOP                    NOP();

010F 81           RTS                 }
                  __MAIN:
FFFE 01 00 

Our compilers correctly optimize out the syntactically convenient but otherwise do-nothing do..while(0) statement.

The discussion: comp.lang.c