잡담
C/C++의 매크로에서 왜 do{...}while(0) 문을 사용할까?
LDobac
2017. 8. 11. 23:52
예전부터 코코스, 언리얼 소스를 뜯어보나, 아니면 다른 오픈소스 엔진을 뜯어보다 보면 한번씩
#define foo(X) do{ ... } while(false) 문을 사용하는 것을 많이 봐왔는데. 이제 도저히 이게 뭔지 궁금해서 직접 구글에 검색해서 찾아 보았다.
만약 이런 매크로 함수가 있다고 한다면
1 2 3 4 | #define DoSomething(X) printf("Hello!"); if(A) DoSomething(2); | cs |
1
2
if(A)
printf("Hello!");
이러면 우리가 의도한 대로 됬지만 만약 다음처럼 전처리문이 2줄 이상이라면 어떻게 될까?
1 2 3 4 5 6 7 | #define DoAction(X) \ printf("Hello!"); \ do_other(); if(A) DoAction(2); | cs |
1
2
3
if(A)
printf("Hello!");
do_other();
이렇게 됨으로써 한가지 문제가 생겨버렸다, C/C++의 if 문은 코드가 한 줄일경우 중괄호를 생략하여서 사용 가능하다. 중괄호가 없는 if문은 다음 한줄까지를 if문 내의 표현식으로 인식한다는 것이다. 그렇게 되면 다음의 do_other 함수는 무조건 실행되게 된다.
다음과 같이 do {...} while문을 사용한다면
1 2 3 4 5 6 7 | #define DoAction(X) do { \ printf("Hello"); \ do_other(); \ } while(false) \ if(A) DoAction(2); | cs |
1 2 3 4 5 | if(A) do { printf("Hello"); do_other(); } while(false) | cs |
이러한 방식이 생기게 된 이유는 전처리기가 너무 정직함과 동시에 사람의 실수를 막기 위해 생긴거 같다.
사실 나는 if 문을 사용하든 for문을 사용하든 무조권 중괄호를 사용하여 영역을 확실하게 구분하게 하여 위와 같은 상황은 잘 일어날거 같지는 않지만 혹시 모를 상황에 자주 쓰는 매크로는 위와같은 처리를 해 두는것이 좋을꺼 같다.
참고 자료
https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for