조건부 컴파일
조건에 따라 특정 부분의 소스코드를 컴파일에 포함 혹은 배제시키는 문법이다
#ifndef NULL
#define NULL (0)
#endif
/* NULL이 정의 안되어있다면, 값이 0인 NULL을 정의. */
#if !defined(NULL)
#define NULL (0)
#endif
/* NULL이 정의 안되어있다면, 값이 0인 NULL을 정의. */
#if defined(NULL)
#undef NULL
#endif
/* NULL이 정의되어 있다면, 그 정의를 해제시킴. */
#define NULL (0)
/* 값이 0인 NULL을 정의. */
조건부 컴파일 주의점
#define A
#if defined (A) // 참
#define LENGTH (10)
#endif
#if A // 거짓, A에 어떤 정의도 해주지 않았기 때문에
#define LENGTH (10)
#endif
인클루드 가드
헤더 파일들이 서로가 서로를 인클루드 하는 상황이 생길 수 있다
이를 순환참조(Circular Dependency)라고 부르며, 해결법 중 하나가 인클루드 가드이다
헤더 파일의 추가 가능 여부를 define으로 확인하는 것이다
#ifndef A_H // 만약 A_H가 정의되어 있지 않다면,
#define A_H // A_H를 정의
// 이 부분에 소스코드가 있다면, 해당 소스코드는 A_H가 정의되어 있지 않을 때 실행
#endif
인클루드 가드 예시
// apple.h
#ifndef APPLE_H
#define APPLE_H
#include "strawberry.h"
#endif // APPLE_H
// strawberry.h
#ifndef STRAWBERRY_H
#define STRAWBERRY_H
#include "apple.h"
#endif // STRAWBERRY_H
// main.c
#include <stdio.h>
#include "apple.h"
int main(void)
{
return 0;
}
조건부 컴파일의 다양한 예시
- 버전 관리
int spawn_monster(...)
{
get_monster_skin();
get_monster_stat();
#if defined(FILE_VERSION_2)
use_custom_skin(...);
/* 어딘가에 #define FILE_VERSION_2라는 코드가 없으면 컴파일에 포함 안됨. */
#elif defined(FILE_VERSION_3)
use_custom_voice(...);
#else
use_default_skin(...);
use_default_voice(...);
#endif
calculate_spawn_location();
return TRUE;
}
- 주석 처리
#if 0 /* 0을 1로 바꾸면 포함, 그냥 두면 주석. 편함. */
... 명령어 ...
#endif
- 에러
컴파일 도중 강제로 컴파일 에러 발생시키는 매크로이다
메세지를 꼭 큰 따옴표로 감싸지 않아도 된다
/* version.h [분할 컴파일]*/
#define VERSION 10
/* builder.h [분할 컴파일]*/
#if VERSION != 11
#error "Unsupported version."
#endif
매크로 함수
장점:
함수 호출이 아니라 소스코드 복붙의 개념이다
따라서 함수 호출에 대한 overhead가 없다
단점:
디버깅이 불가능하다
중단점이 걸리지 않는다
매크로 함수의 예시
매크로 사용 시 여러 줄을 사용해야 하는 경우
아래와 같이 \를 사용하면 된다
#include <stdio.h>
#define POW(n,e,i,r) r = 1; \
for (i = 0; i < e; ++i) \
{ \
r *= n; \
} \
int main(void)
{
int i;
int num = 2;
int exp = 8;
int res;
POW(num, exp, i, res);
printf("%d", res);
return 0;
}
'C > [코드조선] C 핵심' 카테고리의 다른 글
[C] 분할 컴파일과 라이브러리 (0) | 2024.02.18 |
---|---|
[C] 전처리기 지시자와 컴파일 플래그 (0) | 2024.02.17 |
[C] 입출력 리디렉션, 커맨드 라인 인자 (0) | 2024.02.17 |
[C] 파일 입출력 (2) (0) | 2024.02.16 |
[C] 파일 입출력 (1) (0) | 2024.02.16 |