#define catch_exception(ce_arg) fprintf(stdout, "%sn", ce_arg) 

if ( state == -1 ) 
  catch_exception("state is null"); 


위와 같은 코드가 있을때 전처리 과정에 의해 아래와 같은 정상적인 코드로 변환되겠죠? 


if ( state == -1 ) 
  fprintf(stdout, "%sn", "state is null"); 


그런데.. 아래와 같이 define을 사용하였다고 가정합니다. 


#define catch_exception(ce_arg) 
  fprintf(stdout, "%sn", ce_arg); 
  do_something(); 

if ( state == -1 ) 
  catch_exception("state is null"); 


위의 코드는 의도하였던 바와 다르게 아래와 같이 변환됩니다. 


if ( state == -1 ) 
  fprintf(stdout, "%sn", "state is null"); 
  do_something(); 


do_something() 문은 if의 제어를 받지 않게 되는 위치에 놓이게 되겠죠? 
의도한 바에 따른 코드는 아래와 같습니다. 


if ( state == -1 ) 
{ 
  fprintf(stdout, "%sn", "state is null"); 
  do_something(); 
} 


이렇나 경우에  #defines  do { ... } while(0)을 사용하게 됩니다. 


#define catch_exception(ce_arg) 
  do { 
    fprintf(stdout, "%sn", ce_arg); 
    do_something(); 
  while ( 0 ) 


변환된 코드는 아래와 같습니다. 


if ( state == -1 ) 
{ 
  do 
  { 
    fprintf(stdout, "%sn", "state is null"); 
    do_something(); 
  } 
  while ( 0 ); 
} 

또 다른 경우를 살펴보면 아래와 같습니다.

#define exchange(x, y) 
    { int tmp; tmp = x; x = y; y = tmp; } 


익숙한 코드죠? 우선 이러한 매크로가 선언되었습니다. 


if ( x > y ) 
  exchange(x, y); 
else 
  do_something(); 


이 코드는 아래와 같이 변환되겠죠? 


if ( x > y ) 
{ 
  int tmp; 
  tmp = x; 
  x = y; 
  y = tmp; 
} 
; 
else 
  do_something(); 


끝에 세미콜론 하나가 무척이나 거슬림을 넘어서 맘아프게하죠? ^^ㅋ 
이 경우에도  #defines  do { ... } while(0)을 사용하게 됩니다. 


#define exchange(x, y) 
    do { int tmp; tmp = x; x = y; y = tmp; } while ( 0 ) 

if ( x > y )
  exchange(x, y);
else
  do_something();


if ( x > y ) 
  do 
  { 
    int tmp; 
    tmp = x; 
    x = y; 
    y = tmp; 
  } while ( 0 ); 
else 
    do_something();