42서울 개포 클러스터에서 문득 Linux, Dart, Flutter 등 많은 프로젝트를 오픈소스라고 말하는데 그러면 C 언어도 오픈소스인가 하는 의문이 생겼어요.
찾아보니 C 언어는 소프트웨어가 아니였어요. 그래서 오픈소스라기 보다는 정의된 표준이였어요. 그래서 제각기 다양한 컴파일러를 구체적으로 구현하면서 정의된 표준을 준수하면서 C 컴파일러 오픈소스가 많아지게 되었어요. 예) GCC, MSVC
C 언어는 언어를 위한 '표준'만을 말하는 거였어요. 누군가 소유할 수 있는 것이 아니고 모두가 사용할 수 있는 언어였어요. 이 표준을 사용해서 컴파일러나 인터프리터를 개발하는 건 누구나 가능했어요. 그렇지만 컴퓨터를 모르는 사람과 적은 인원으로는 언어를 만드는 게 쉬운 일이 아니였을 거예요.
C 언어란 무엇인가?#
C 언어는 프로그램이 실행되기 위해 따라야 할 규칙들을 기준으로 .c
파일 형식으로 작성돼요. 작성된 소스 코드는 사람만 이해할 수 있으며, 컴퓨터가 직접 이해할 수 있는 것은 아니에요. 컴퓨터가 이해할 수 있도록 소스 코드를 기계어로 변환하는 과정이 필요한데, 이 과정에서 컴파일러라는 도구가 필수적이에요.
컴파일 과정에서는 소스 코드의 문법 오류를 검사하고, 해당 파일이 컴퓨터에서 실행 가능한 상태로 변환돼요.
- 전처리기를 통해 코드 전처리를 수행
- 컴파일러가 전처리된 파일을 기계어로 변환하여 개체 파일을 생성
- 링커가 개체 파일과 필요한 스타트업 코드 등을 결합해 최종 실행 파일을 생성
C 언어 컴파일러는 왜 다양할까요?
C 언어는 다양한 운영 체제와 하드웨어에서 사용되기 때문에, 각 환경에 최적화된 컴파일러들이 필요했어요.
다양한 요구와 성능, 기능에 맞추어 다른 컴파일러가 개발되었고 오픈소스 컴파일러는 커뮤니티에서 자유롭게 수정되고 배포되어 특정 기능이나 환경에 맞춘 다양한 버전들이 파생되었어요.
컴파일 과정#
컴파일 과정은 여러 단계로 이루어집니다. 이를 gcc
명령을 통해 단계별로 확인할 수 있어요.
- 전처리:
gcc -E main.c -o main.i
전처리기는#include
,#define
등의 전처리 명령을 해석하고, 코드에서 필요한 외부 파일과 매크로를 처리하여 전처리된 파일을 생성해요 - 컴파일:
gcc -S main.i -o main.s
전처리된 파일을 어셈블리 언어로 변환돼요. 어셈블리 언어는 특정 하드웨어에서 실행될 수 있도록 변환된 코드의 중간 형태예요 - 어셈블:
gcc -c main.s -o main.o
어셈블리 코드를 기계어로 변환하여 개체 파일(.o
)을 생성해요 - 링크:
gcc main.o -o main.exe
링커는 개체 파일을 Startup 코드 등과 결합해 실행 파일을 만들어요. Startup 코드는 프로그램 실행 전 필요한 준비 작업을 수행하며,main()
함수를 호출하는 역할을 해요.
Where focus goes, energy flows.
— Tony Robbins