2008/02/29 10:19
FAQ/DoWhile0 wkoh+development2008/02/29 10:19
커널 코드를 보다보면 #define do {...} while(0) 가 종종 쓰인다. 이러한 부분이 kernelnewbies.org 에 있어서 간단히 정리해 놓는다.
- (Dave Miller는) Empty statements의 경우 컴파일러가 warning으로 간주하기 때문에 dowhile0 블럭을 사용한다.
- (Dave Miller는) local variables를 선언하는 basic block으로 간주할 수 있다.
- (Ben Collins는) 이는 조건이 담긴 코드에서 보다 복잡한 메크로를 사용할 수 있도록 지원하다고 말하고 있다. 만약 몇줄로 이뤄진 하나의 매크로가 다음과 같다면...
#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);;
여기서 보이다시피 원치않게도 do_something_useful은 조건문에 속하지 않게 된다. 그래서
dowhile0를 사용하여
if (blah == 2)
do {
printf("arg is %s\n", blah);
do_something_useful(blah);
} while (0);
와 같은 형태로 만드는 것이다.
- (Per Persson은) Muller 와 Collins가 지적한 바와 같이 block statement를 사용하길 원할때, 몇몇줄의 코드와 local variables를 선언할 수 있다고 언급했다. 그러나 일반적으로 사용할 때는 차라리 다음과 같이 사용하는 편이 더욱 직관적이겠다.
#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
그러나 이는 어떤 경우에 대해서는 정상적으로 동작하지 않는다. 다음 코드는 두개의 브랜치를 가지는 If-statement 이다.
if (x > y)
exch(x,y); // Branch 1
else
do_something(); // Branch 2
그러나 이는 오직 하나의 브랜치만을 갖고있는 if-statement로 해석되게 된다. 다음과 같이...
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();
블럭 뒤에 바로 나오는 semi-colone(;)이 문제가 된 것이다. 이에 대한 해결책은 역시 dowhile0를 사용하는 것이다. 그러면 블럭의 capabilities를 갖는 하나의 statement 를 사용하게 되는 것으로, 다음과 같이 해석될 것이다.
if (x > y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while(0);
else
do_something();
- (Bart Trojanowski는) gcc는 dowhile0 블럭을 대체할 수 있는 Statement-Expressions를 제공하고 있다고 언급했다. 이는 위의 장점에 더욱 읽기 쉽다라는 추가적인 장점을 제공한다.
#define FOO(arg) ({ \
typeof(arg) lcl; \
lcl = bar(arg); \
lcl; \
})
이올린에 북마크하기
