- 매크로 안에서 지역 변수를 선언할 수 있다.
- 복잡한 매크로를 만들 수 있다. 예를 들어 아래와 같이 매크로를 선언하고:
#define FOO(x) \
printf("arg is %s\n", x); \
do_something_useful(x);
아래와 같이 사용하면:
if (blah == 2)
FOO(blah);
이렇게 해석된다:
if (blah == 2)
printf("arg is %s\n", blah);
do_something_useful(blah);;
의도한 바와는 다르게 base == 2 일때 do_something_useful(blash) 는 실행되지 않는다. 이 매크로를 do{...}while(0) 을 사용해서 만들었다면 아래와 같은 코드를 얻을 수 있다:
if (blah == 2)
do {
printf("arg is %s\n", blah);
do_something_useful(blah);
} while (0);
매크로를 단지 블럭({...}) 으로만 묶을 경우 복잡한 매크로 선언이나 지역 변수 사용은 가능하나 한가지 문제가 생긴다. 아래 예를 들어:
#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
이 매크로를 if 구절에 사용하면:
if(x>y)
exch(x,y); // Branch 1
else
do_something(); // Branch 2
해석하면 아래와 같은 코드가 된다:
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();
세미콜론(;) 으로 인해서 if 구절이 완료가되고 그 다음 else 구절은 에러구문이 된다.
이런 문제를 해결하기 위해서 매크로를 do{...}while(0) 로 묶는다. 이럴경우 컴파일러는 코드를 아래와 같이 해석한다:
if(x>y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while(0);
else
do_something();