개발/C & C++

선행처리기(Preprocessor)

김알리 2024. 3. 13. 17:18
728x90
반응형

선행처리기를 사용하는 이유

요약하면, 컴파일 전에 먼저 처리하고 싶은 것이 있기 때문이다.

 

C 코드를 실행 파일로 만들기 위해서는 선행처리 → 컴파일 링킹의 3단계를 거쳐야 한다.

여기서 가장 핵심적인 단계는 '컴파일'인데, 일종의 번역으로 생각하면 된다. C언어를 컴퓨터가 알아들을 수 있게 번역하는 것이다.

 

그리고 선행처리는 코드를 컴파일하기 전, 사용자가 정의한 내용을 일부 먼저 처리하는 과정이다. 

 

종류

선행처리기 기능
#include 파일 포함
#define 매크로 정의
#if, #else, #elif, #endif 조건부 컴파일

 

#include

JS/TS의 module import, Go의 pkg import와 유사한 개념이다.

다른 파일에 있는 코드를 사용하기 위해, 헤더 파일(*.h)을 함께 컴파일하려고 사용한다. 

#include <경로|파일명>
#include "경로|파일명" 
// 위와 같은 두 가지 형태로 사용 가능

 

#define

다른 언어/생태계의 .env 파일이나 config 파일과 유사한 개념인 것 같다. 

매크로(macro) 자체는 '단순 치환되는 자료'를 말하는데, 상수와 함수를 정의할 수 있다.

 

방통대 교재에서는 매크로 함수를 정의하면 이런 장점이 있다고 한다.

1. 자료형 명시할 필요 없음

2. 한두 줄 정도의 간단한 함수는 일반 함수로 정의하는 것 보다 빠름

 

그러나 찾아보니 어지간하면 매크로를 쓰지 않는 것이 국룰인 것 같다.

상수의 경우는 const 나 enum을 사용하기를 추천하고, 함수는 그냥 정의하라는 의견이 대다수였다.

 

#if, #else, #elif, #endif

#if는 컴파일할 때 해당 코드를 포함시킬지 여부를 정의하는 기능이다.

조건문이 생길 때마다 코드에서 분기가 일어나기 때문에 프로그램의 성능이 저하된다.

때문에 아예 컴파일 전에 일부 조건문을 제거해 버리는 것이다.

#define을 굳이 사용해야 할 경우를 꼽자면 바로 #if를 사용하는 경우이다. 

 

아래 예시를 보면 이해가 더 쉽다.

일반적인 조건문 if는 컴파일된 결과물에 조건문이 포함되지만, #if를 사용하면 컴파일 후 조건문이 사라지는 것을 알 수 있다.

 

 

// 컴파일 전
#include <stdio.h>
#define COND 1

void main() {
	if (COND)
		printf("조건 1\n");
	else
		printf("조건 %d\n", COND);
}


// 컴파일 후
void main() {
	if (COND)
		printf("조건 1\n");
	else
		printf("조건 %d\n", COND);
}
// 컴파일 전
#include <stdio.h>
#define COND 1

void main() {
#if COND
	printf("조건 1\n");
#else
	printf("조건 %d\n", COND);
#endif
}


// 컴파일 후
void main() {
	printf("조건 1\n");
}

 

728x90
반응형