C Primer Plus - 1장: 준비

요나·2023년 5월 12일
0

C Primer Plus

목록 보기
1/3
post-thumbnail

본 포스팅은 Stephen Prata의 C Primer Plus를 읽고 요약한 글입니다.


컴퓨터는 어떻게 동작하는가?

  • CPU의 기능은 간단하다. 메모리에서 명령 하나를 가져온다. 다음 명령을 가져온다. 이것을 반복한다.
  • CPU는 무수한 register들로 이루어진 자신만의 작업공간을 가지며, 각 레지스터는 하나의 number를 저장한다. 한 레지스터는 다음 실행할 명령의 메모리 주소를 저장한다. CPU는 이 정보를 기반으로 다음 실행할 명령을 불러온다. CPU는 가져온 명령을 또 다른 레지스터에 저장하고, 앞선 주소 레지스터를 다음에 실행할 명령이 있는 주소로 갱신한다.
  • CPU는 instruction set이라고 부르는 한정된 개수의 명령 리스트를 가지며, 이 리스트에 포함된 명령만 이해할 수 있다.
  • 컴퓨터의 동장 방식에 대해 결론을 내리면 한마디로: “컴퓨터에게 어떤 일을 시키려면 기계어로 작성된 명령 리스트(프로그램)을 컴퓨터에게 제공해야 한다”는 것이다.

언어 표준

  • 여러 C 컴파일러들이 하나의 승인된 표준을 준수할 때 컴파일이 가능하다.
  1. ANSI/ISO C 표준
    • 미국표준협회(ANSI)와 국제표준화기구(ISO)가 각각 1989년, 1990년에 결정한 최초의 공식적 표준.
    • C 언어(그리고 C 라이브러리)에 대한 이해하기 쉽고 엄격한 표준이 필요해짐에 따라 만들어졌다.
    • “프로그래머를 믿자.” “C 언어를 작고 단순하게 유지하자.” “이식성이 훼손되더라도 빠르게 실행되게 하자”와 같은 아이디어들을 기반으로 정립되었다.
  2. C99 표준
    • 1999년 ANSI/ISO 공동위원회가 제정한 표준으로, 기존의 원칙들을 고수하되 조금 보충하는 것.
    • Unicode 처리, 64bit 프로세서 지원, 계산 실용성 개선 등이 이루어졌다.
    • 모든 컴파일러들이 C99 개정표준을 구현하고 있지 않기 떄문에 설정을 변경해야하는 경우도 있다.
  3. C11 표준
    • “프로그래머를 믿자”는 원칙을 완화하여 보안 및 안전에 대한 시대적 요청에 따라 개선.
    • C99에 대한 미지원이 많았기 때문에, C99의 일부 기능이 선택사항이 되었다.
    • 컴퓨터에 멀티 프로세서가 사용되기 시작함에 따라 동시성 프로그래밍 지원을 선택사항으로 추가했다.

컴파일

  • 컴파일러는 source code를 excutable code(기계어)로 변환시키는 프로그램이다.
  • 컴퓨터는 기종마다 사용하는 기계어(&어셈블리)가 다르기 때문에 컴파일러는 이에 맞는 기계어로 번역한다.
  • 또한 C 컴파일러는 C 라이브러리에 들어 있는 코드를 불러와 최종 프로그램에 결합시킨다.
    • 정확히는 컴파일러가 사용자를 대신하여 linker를 실행시키며, 링커가 라이브러리 함수를 불러들인다.
  • 최종적으로 컴파일러는 컴퓨터가 이해할 수 있고 사용자가 실행시킬 수 있는 excutable file을 결과물로 만든다.
  • 컴파일러는 컴파일 중 문법을 검사하고 에러가 발생되면 실행 파일을 만들지 않는다.

프로그래밍 계획하기

  • ‘프로그램 목적 정의’와 ‘프로그램 설계’를 건너 뛰고 바로 코드 작성에 뛰어들기 쉽다.
  • 하지만 프로그램이 길어지고 복잡해지면 전체 과정을 머릿속으로 그리거나 에러를 찾아내는 것이 어려워진다.
  • 코딩하기 전 프로그램의 목적과 설계의 윤곽을 작성해봄으로써, 계획하고 설계하는 습관을 기르자.

오브젝트 파일, 실행 파일, 라이브러리

  • C 환경은 소스 코드 파일을 실행 가능한 기계어 코드가 들어있는 실행 파일로 변환시키는 과정을 compiling과 linking 두 단계로 나누어 처리한다.
    • 컴파일러는 소스 코드를 중간 코드로 변화하며, 링커는 중간 코드를 다른 코드와 결합하여 실행 파일을 만든다. 이렇게 두 단계로 분리되었기에 모듈화가 가능하여, 각각의 모듈을 따로 컴파일한 후, 컴파일된 모듈들을 링커로 결합할 수 있게 된다.
    • 하나의 모듈만 수정이 필요한 경우 다른 모듈들은 컴파일하지 않으며, 링커는 컴파일된 라이브러리 코드를 가져와 프로그램에 결합한다.
  • 중간 파일을 만드는 방법은 여러 가지가 있는데, C 환경이 채택하고 가장 널리 쓰이는 방법은 소스코드를 기계어 코드로 변환하여 그 결과를 object (code) file로 저장하는 것이다.
  • 오브젝트 파일은 기계어 코드를 가지고 있지만 두 가지 요소를 결여하고 있다.
    1. start-up code: 프로그램과 OS 사이의 인터페이스를 담당하는 코드로, 운영체제 마다 프로그램을 처리하는 방식이 다르기 때문에, 동일한 오브젝트 코드여도 각자에게 맞는 서로 다른 시동 코드가 필요하다.
    2. library rutine code(=function): 오브젝트 코드 파일은 함수의 코드를 가지고 있지 않으며, 단순히 어떠한 함수를 사용하라고 지시하는 명령만 가지고 있다. 실제 함수의 코드는 라이브러리라 부르는 다른 파일에 저장되어 있으며, 그 안에는 많은 함수들의 오브젝트 코드가 들어있다.
  • 링커는 오브젝트 코드, 시동 코드, 라이브러리 코드 세 가지를 묶어서 하나의 실행파일로 만드는 역할을 한다.
    • 라이브러리 코드를 사용할 때는 프로그램이 사용하는 함수에 대한 코드만 추출하여 사용한다.
  • 오브젝트 파일과 실행 파일은 둘 다 기계어 명령들로 이루어져 있다는 점에서는 같지만, 오브젝트 파일은 소스 코드만을 기계어로 번역한 코드이고, 실행 파일은 라이브러리 루틴과 시동 코드를 포함하고 있다.

Unix 시스템에서의 컴파일

  • C 언어에 대한 정의 그 자체였던 Unix C 컴파일러(cc)는 표준에 따라가지 못해 사라졌지만, 대부분의 Unix 시스템은 다른 컴파일러에 대한 alias로 cc 명령을 사용한다.
  • example.c를 컴파일했을 때 실행파일(a.out)만 보이고 example.o 오브젝트 코드 파일이 보이지 않는 이유는 실행 파일을 만들고 나서 링커가 삭제해버렸기 때문이다.

GNU 컴파일러 컬렉션과 LLVM 프로젝트

  • GNU 프로젝트는 Unix 스타일의 오픈소스 소프트웨어를 다량으로 만든 대규모 협업 프로젝트인데, GNU가 만든 것 중 하나가 GNU Compile Collection(gcc)이며, 이중 C 컴파일러가 들어있다.
  • LLVM 프로젝트는 일리노이 대학 연구 프로젝트로 시작된 컴파일러 관련 오픈소스 컬렉션이며, 이중 Clang 컴파일러(clang)가 C코드를 처리한다.
  • 둘다 C 표준을 매우 잘 준수하고 있으며, 각 C 표준에 따르는 런타인 옵션을 요구할 수 있다.
# clang도 동일하다.
gcc -std=c99 example.c # C99 표준
gcc -std=c1x example.c # C11 표준 초안
gcc -std=c11 example.c # C11 표준
profile
var yona = IOSDeveloper(stage: 0)

0개의 댓글