[C] C언어 컴파일 1/4단계: 전처리기(Preprocessor)

Yongjun Park·2022년 1월 24일
0
post-thumbnail

커맨드

$ cpp main.c main.i
$ cpp sum.c sum.i

cpp는 전처리 기능을 수행해주는 프로그램, 즉 전처리기다.
cpp = C/C++ PreProcessor의 준말

cpp 프로그램이 없어서 실행을 하지 못한다면, 다음과 같은 명령어도 사용 가능하다.

$ gcc -E main.c -o main.i
$ gcc -E sum.c -o sum.i

gcc -E 옵션에 대한 자세한 내용은 gcc 기본 옵션 정리를 참고하시기 바랍니다.

이해를 돕기 위해, 생성된 main.i 파일을 보여주자면 다음과 같다.

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"
int sum(int *a, int n);

int array[2] = {1, 2};

int main(void)
{
 int val = sum(array, 2);
 return val;
}

#include

헤더를 #include하면 어떻게 표시될까?
main.c의 함수 sum 선언 부분만 떼어 sum.h라는 별도의 헤더 파일로 만들어보았다.

// main.c
#include "sum.h"

int array[2] = {1, 2};

int main()
{
    int val = sum(array, 2);
    return val;
}
// sum.h
#ifndef SUM_H
# define SUM_H

int sum(int *a, int n);

#endif

이 경우, main.i 파일은 다음과 같이 생성된다.

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"


# 1 "sum.h" 1



int sum(int *a, int n);

int array[2] = {1, 2};
# 4 "main.c" 2

int main()
{
 int val = sum(array, 4242);
 return val;
}

include를 사용하면 헤더 파일의 내용 전체가 main.i 파일 내에 그대로 추가되는 것을 볼 수 있다.

#define

매크로를 define하는 경우 어떻게 처리될까?
본래(헤더로 나누기 전) main.c 파일에 #define X 4242를 추가해보았지만, main.i 파일에는 변화가 없었다.

하지만 X를 실제로 코드에서 사용하는 경우 변화가 나타난다.

// main.c
#define X 4242

int sum(int *a, int n);

int array[2] = {1, 2};

int main()
{
    int val = sum(array, X);
    return val;
}

main.i 파일은 다음과 같다.

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"


int sum(int *a, int n);

int array[2] = {1, 2};

int main()
{
 int val = sum(array, 4242);
 return val;
}

즉, X로 처리되었던 부분이 4242로 변경되었다.
재미있는 점은, 전처리에서 바꾸는 건 말 그대로 문자열을 치환한다는 사실이다.

쓸모 없지만, 나만 알아보는 코드를 원한다면 main.c를 다음과 같이 짤 수도 있다.

// main.c 
#define X 4242
#define FTFT val
#define R return

int sum(int *a, int n);

int array[2] = {1, 2};

int main(void)
{
	int FTFT = sum(array, X);
	R FTFT;
}

이렇게 해도 전처리 결과는 바로 위의 main.i 파일과 동일하다.

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"


int sum(int *a, int n);

int array[2] = {1, 2};

int main()
{
 int val = sum(array, 4242);
 return val;
}
profile
추상화되었던 기술을 밑단까지 이해했을 때의 쾌감을 잊지 못합니다

0개의 댓글