DEBUG macro

Computing 2008.05.20 13:19
C 로 프로그래밍을 하는 사람이라면 거의 모두들 한번쯤 디버깅 메세지를 출력하는 문제에 대해 고민해 보았을 것이라 생각한다.
아마도 빌드 모드가 디버그일 경우에만 매크로가 확장되고, 릴리즈일 경우에는 사라지도록 다음과 같은 매크로를 정의해서 사용했을 것이다 :
그런데 위의 매크로를 쓰면서 불편한 것이 하나 있으니, 바로 다음과 같이 사용할 수 밖에 없다는 것이다 :
그렇다. 치명적인(!!!) 약점이 있으니, 바로 괄호를 두개 써야 한다는 것이다.

C99 표준에서 이 문제를 해결할 수 있도록 매크로에 가변 인자를 지원하는 기능(?)이 포함되었으나 그 표준정의 자체가 한계를 가지고 있는 데다가 (함수의 가변 인자와는 달리 반드시 최소 하나의 인자를 받아야만 한다는 제약사항이 있다) 지원하는 컴파일러마저, VC++ 2005 이상에서만 지원한다. 물론 gcc 는 당연히 지원하는 데다가 플러스 알파로, C99 표준의 약점을 해결하기 위한 확장까지 제공하긴 하지만, 여기서 내가 원하는 것은 모든 컴파일러에서 통용되는 방법이므로 매크로 가변인자 기능을 사용하기에는 무리가 있다.

그러면 보기 싫은 두개의 괄호를 어떻게 해결할까...

아래와 같이 DEBUG 매크로를 정의해 보자.
혹은
컴파일러의 최적화에 의존을 하게 되면 필요없는 printf 는 사라지게 된다. 게다가 요즘 컴파일러는 이정도의 최적화는 기본이다.

재미있는 것은, 아래의 것 보다, 함수 이름을 (void) 로 치환해 버리는 것인데,,,

그러면 위의 첫번째 방법을 사용했을 때 아래와 같은 코드는
프리프로세서를 거치고 나면, 디버그 모드에서는
디버그 모드가 아니면
로 확장되게 된다.

얼핏 보아서는 이게 컴파일이 될까 하는 생각이 들겠지만,
놀랍게도 컴파일이 된다! +_+ (콤마 연산자임)

정말 기발(!)하지 않은가?
나는 수년간 괄호 두개가보기 싫은데도 불구하고 달리 뾰족한 방법을 생각하지 못해서 괄호 두개를 계속 써 왔었는데, 저 방법을 보는 순간 갑자기 마구 억울해지기 시작했다.

물론, 아래의 다소 암호같은(!) (void) 로 치환하는 방법은 (댓글에서 han9kin 님이 지적했듯이) 콤마 연산자로 구분된 각각의 연산이 실행이 되어 버려서 변수의 값이 변할 수 있는 위험이 존재한다.

그러니 뭔가 특이한 걸 써서 "튀"기 보다, 안전하게 while (0) 로 치환하는 방법을 선택하도록 하자.

tags :
Trackbacks 0 : Comments 2
  1. BlogIcon han9kin 2008.05.20 13:56 신고 Modify/Delete Reply

    #define DEBUG (void)

    #define DEBUG while (0) printf
    는 제가 보기에는 너무 달라보입니다.

    전자는 인자들에 대한 연산이 모두 실행될 것이고, 후자는 실행되지 않을 겁니다.
    물론 디버깅 정보 출력하는 코드에 연산이 있는 경우는 거의 없겠지만.

    그리고 gcc -W 로 전자를 컴파일하면 다음과 같은 워닝이 나와서 보기가 별로 안좋습니다.
    warning: left-hand operand of comma expression has no effect

  2. BlogIcon Orchistro 2008.05.20 17:04 신고 Modify/Delete Reply

    저도 그래서, 위의 (void) 로 치환한 것은 흥미거리 정도로 생각합니다 :-) 실제는 아래의 while(0) 을 쓰는 것이 나으리라 생각됩니다 :-)

Write a comment