전처리기를 잘 활용하면, 반복되는 코드를 줄이거나, 컴파일할 코드를 조건에 따라 변경하는 등 프로젝트를 개발할 때 있어 편리한 기능들이 많아요. 이번 편에는 조건부 컴파일을 활용해, 디버깅을 위한 코드를 작성해볼게요.
흔히 변수 값을 디버깅하기 위해, 매번 같은 코드를 반복적으로 사용해왔어요.
int x = 5, y = 10;
printf("x = %d\n", x);
printf("y = %d\n", y);
printf 구문 자체는 변수 이름을 제외하면 동일한데, 이를 함수로 만들 수는 없을까요?
이를 위해, 우리는 인자가 있는 매크로를 만들어볼게요.
#define DEBUG_INT(x) printf(#x" = %d", x)
이 매크로에는 인자 x를 받아, 문자열화 연산자 #
을 사용해 변수 이름을 printf의 제어 문자열에 포함시켜줬어요.
이 매크로 함수를 사용하면, 위의 디버깅 코드를 아래와 같이 간략화 할 수 있어요.
int x = 5, y = 10;
DEBUG_INT(x);
DEBUG_INT(y);
앞서, #ifdef
등을 사용해 특정 식별자가 정의되어있는지 확인할 수 있다고 배웠어요. 이를 활용하면, 디버깅 시에만 특정 코드를 포함시켜 코드를 컴파일할 수 있어요.
#define DEBUG
int a = 10, b = 20;
// ...
#ifdef DEBUG // DEBUG 식별자가 정의되어 있을 때
DEBUG_INT(a);
DEBUG_INT(b);
#endif
// ...
위와 같이 코드를 작성하면, 디버깅 시에 DEBUG 식별자를 정의해주기만 하면 필요한 디버그 코드들을 컴파일 시에 포함할 수 있어요. 반대로, 출시할 때는 DEBUG 식별자를 정의하지 않으면 디버그 코드들을 제외하고 컴파일 할 수 있어요.
하지만, 디버깅 시에만 DEBUG 식별자를 정의하면 되는데 굳이 #define DEBUG
를 코드에 작성해야 할까요? 이 문제는 컴파일 시 옵션을 활용해 간단히 해결할 수 있어요.
gcc의 경우, -D
옵션을 사용해 컴파일 시 식별자를 정의할 수 있어요.
$ gcc -D DEBUG code.c
이 경우, 코드에 #define DEBUG
문장을 작성하는 것과 동일해요.
$ gcc -D DEBUG=1 code.c
직접 식별자의 값을 정해줄 수도 있어요. 이 경우는 코드에 #define DEBUG 1
문장을 작성한 것과 같아요.