디버그용으로 printf 를 쓸때가 매우 많다. 디버그 목적으로 무분별하게 printf 를 추가했지만 릴리즈하기전 printf를 지우는 일은
많은 노동력이 든다. 이 노동을 매크로를 이용해서 릴리즈할때는 디버그 목적으로 추가된 printf를 없애는 방법이다.
#if defined DEBUG
#define TRACE(fmt,...) printf(fmt,__VA_ARGS__)
#define TRACE(fmt,...) printf(fmt,##__VA_ARGS__)
#else
#define TRACE(fmt,...)
#endif
키포인트:
#define TRACE(fmt,...) printf(fmt,__VA_ARGS__) 이렇게만 쓸경우 TRACE("test") 와 같이 인자가 하나일때는 오류가 난다.
#define TRACE(fmt,...) printf(fmt,##__VA_ARGS__) 이렇게 ## 토큰 분할 문자를 써야 TRACE("test") 나
TRACE("test %s","test") 등 인자가 하나일때 그 이상일때도 정상적으로 동작한다.
설명 : 가변인자를 사용하는 함수와 매우 동일한 형태의 구현이다. 매크로에서 가변 인자는 가변함수와 마찬가지로 ... 이다.
가변함수에서는 va_list, va_start(), va_arg(), va_end() 로 가변인자를 처리했다. 하지만 매크로 에서는 __VA_ARGS__ 라는 예약어(?)가 이를 처리해 준다.
리눅스와 윈도우에서 테스트 결과 잘 돌아간다.
리눅스 gcc의 경우 가변매크로에서
#define TRACE(fmt,args...) printf(fmt,args)
의 형태도 동작했지만 visual studio 에서는 컴파일조차 하지 못했다. 따라서 __VA_ARGS__ 를 이용하자.
혹시나 해서 이런 응용 방법도 생각했다. 코딩을 하다보면 printf 같이 단일적인게 아닌 블럭({}) 단위로 디버그 목적의 코드를 작성해야 할 때가 있다.
예를 들어
#if define DEBUG
double avg = sum/total;
printf("%lf",avg);
#endif
이와 같이 디버그 목적으로 한줄이상의 코드가 들어갈때가 있다. (다들 이해하셨을거라 믿는다..)
이때는
#define DEBUGBLOCK(...) do{ __VA_ARGS__ }while(0);
이렇게 정의하고 사용시
void main()
{
char *str = "디버그 목적임";
printf("%s",str);
)
}
위와 같이 사용하면 된다. 왠지 안될거 같은 코드 같다는 생각들을 할텐데.. 나도 아이디어는 떠올랐는데 긴가민가해서 테스트 결과 동작햇다.
'학습자료(~2017) > C,C++' 카테고리의 다른 글
[GCC]gcc 컴파일 옵션 (0) | 2012.08.13 |
---|---|
[C] #if 0 ,#if 1 의 사용의도 (0) | 2012.03.29 |
[ODBC] ODBC 함수 래퍼런스 (0) | 2012.03.09 |
[C 언어] mysql c언어 api라이브러리 사용법 - 펌 (0) | 2012.02.14 |
[C] C LANGUAGE REFERENCE MANUAL C 언어 래퍼런스 메뉴얼 파일 (0) | 2012.01.27 |