assert() 함수 구현시 do while(0)을 사용하는 이유는?

taeyeung의 이미지

assert.h 안에서 assert를 구현할 때 보면은

#define assert(x)  do { \
                                   ..... ; \
                             } while(0)

이렇게 구현해 놓은 것을 볼 수 있는데요

#define assert(x) .....(x)

이렇게 하는 것이 더 간단한데 그렇게 하지 않고서 do while(0)

에 넣어서 구현하는 이유가 무엇인가요?

7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

http://www.kernelnewbies.org/faq/ 에서 "Why do a lot of #defines in the kernel use do { ... } while(0)?" 부분을 살펴보세요.

taeyeung의 이미지

아하 그렇군요, 답변 감사합니다.

매크로 안에 정의 내용이 여러 문장이 되면

매크로가 사용되는 소스에서 조건이 이상하게 걸릴 수가 있어서

이를 방지하는 것이군요

1. 정의된 매크로

#define FOO(x) \
        printf("arg is %s\n", x); \
        do_something_useful(x);

2. 사용 예

if (blah == 2)
                FOO(blah);

3. 실제 내용

if (blah == 2)
                printf("arg is %s\n", blah);
                do_something_useful(blah);;

4. 수정된 매크로

#define FOO(x) do {\
        printf("arg is %s\n", x); \
        do_something_useful(x);
       while(0)

5. 수정된 매크로가 적용된 결과

if (blah == 2)
                do {
                        printf("arg is %s\n", blah);
                        do_something_useful(blah);
                } while (0);
kane의 이미지

내용을 옮기시면서 하나 빠뜨리셨기에..

블럭을 사용하기 위해서만이라면
do { } while(0) 대신 { } 를 사용하는 것도 가능하지만,
추가로 붙는 ';' 때문에
do { } while(0) 를 사용한다는 내용도 쓰여있군요.

if (...)
  MACRO(arg);
else
  statement;

에서

MARCO가 { }이면

if (...)
  { ... }
  ; /* empty statement */    <-- 요 부분 때문에 아래의 else에서 에러
else
  statement;

... 같은 문제가 발생할 수 있다는군요.
markboy의 이미지

예전에 비슷한 주제로 kldp에 글이 올라온 적이 있었습니다. (커널프로그래밍QnA에 올라왔었군요 :) )

http://bbs.kldp.org/viewtopic.php?t=45045