오랜 역사를 자랑하는 C는 여전히 프로그래밍에서 가장 중요한 언어다. 특히 C는 임베디드 시스템과 고성능 하드웨어를 개발할 때 진면모를 발휘하며, 소프트웨어 엔지니어링, 항공우주 연구의 핵심 언어로 자리 잡았다. 무궁무진한 C의 가능성을 믿고, C의 심화 개념과 활용법을 알아보고 싶다면 이 책을 펼칠 차례다.
실제 애플리케이션 개발과 유지 보수에 필요한 기초와 고급 지식을 모두 담았다. C와 유닉스의 역사부터 객체지향, 커널, 스레드, 프로세스, 다른 언어와의 통합에 이르기까지 폭넓은 주제를 살펴본다. 이 책을 통해 여러분의 스킬을 한 단계 높여 배운 내용을 실질적으로 활용할 수 있는 C 전문가로 거듭나길 바란다.
저자소개
저자
캄란 아미니
임베디드 및 커널 전문 개발자. 이란의 여러 유명 회사에서 시니어 엔지니어, 아키텍트, 컨설턴트, CTO로 근무했습니다. 2017년에는 유럽으로 건너가 제퍼슨(Jeppesen), 아데코(Adecco), 톰톰(TomTom), 액티브비디오 네트웍스(ActiveVideo Networks)와 같은 명망 높은 회사에서 시니어 아키텍트 겸 엔지니어로 근무했습니다. 암스테르담에 머무르는 동안 이 책을 집필했으며 주된 관심 분야는 컴퓨터 이론, 분산 시스템, 머신러닝, 정보 이론, 양자 컴퓨터입니다. 직업적 커리어를 쌓으면서 천문학과 행성학도 공부합니다. 우주의 초기 발생, 블랙홀의 기하학, 양자장론, 끈 이론 분야에 학술적 관심을 두고 있습니다.
역자
박지윤
판교의 한 프런트엔드 개발자. C 언어에 관심이 있는 프런트엔드 개발자라니, 하나만 잘하기에도 벅찬 인생이지만 이 책의 저자만큼이나 관심사가 넓은 편입니다. 언젠가 웹 공간에 원하는 비주얼과 사운드를 펼쳐 놓을 수 있기를 희망하며 관련 공부를 하고 있습니다. C 언어에 대한 관심은 사운드/오디오 개발에서 비롯했습니다. 우주에 대해 캄란 아미니만큼 학술적 관심이 있지는 않지만, 블랙홀에 대한 최신 소식이 나오면 찾아보거나, 물리학자 카를로 로벨리(Carlo Rovelli)의 신간이 나오면 사서 읽어보곤 합니다.
목차
[PART I C 프로젝트 빌드]
CHAPTER 1 필수 요소
1.1 전처리기 지시자
1.2 포인터 변수
1.3 함수
1.4 함수 포인터
1.5 구조체
1.6 마무리
CHAPTER 2 소스 코드에서 이진 파일로
2.1 표준 컴파일 파이프라인
2.2 전처리기
2.3 컴파일러
2.4 어셈블러
2.5 링커
2.6 마무리
CHAPTER 3 목적 파일
3.1 ABI
3.2 목적 파일 형식
3.3 재배치 가능한 목적 파일
3.4 실행 가능한 목적 파일
3.5 정적 라이브러리
3.6 동적 라이브러리
3.7 마무리
[PART II 메모리]
CHAPTER 4 프로세스 메모리 구조
4.1 프로세스 메모리 레이아웃
4.2 메모리 구조 알아보기
4.3 정적 메모리 레이아웃 검사하기
4.4 동적 메모리 레이아웃 검사하기
4.5 마무리
CHAPTER 5 스택과 힙
5.1 스택
5.2 힙
5.3 제한된 환경에서의 메모리 관리
5.4 마무리
[PART III 객체지향]
CHAPTER 6 OOP와 캡슐화
6.1 객체지향적 사고
6.2 C가 객체지향이 아닌 이유
6.3 캡슐화
6.4 마무리
CHAPTER 7 합성과 집합
7.1 클래스 간의 관계
7.2 객체 대 클래스
7.3 합성
7.4 집합
7.5 마무리
CHAPTER 8 상속과 다형성
8.1 상속
8.2 다형성
8.3 마무리
CHAPTER 9 추상화와 C++의 OOP
9.1 추상화
9.2 C++의 객체지향 구성물
9.3 마무리
[PART IV 유닉스]
CHAPTER 10 유닉스의 역사와 아키텍처
10.1 유닉스의 역사
10.2 유닉스 아키텍처
10.3 사용자 응용프로그램에 대한 셸 인터페이스
10.4 셸 링에 대한 커널 인터페이스
10.5 커널
10.6 하드웨어
10.7 마무리
CHAPTER 11 시스템 호출과 커널
11.1 시스템 호출
11.2 유닉스 커널
11.3 마무리
CHAPTER 12 최신 C
12.1 C11
12.2 C 표준 지원 버전 찾기
12.3 gets 함수의 제거
12.4 fopen 함수로의 변화
12.5 경계 검사 함수
12.6 값을 반환하지 않는 함수
12.7 타입 제네릭 매크로
12.8 유니코드
12.9 익명 구조체와 익명 공용체
12.10 멀티스레딩
12.11 마무리
[PART V 동시성]
CHAPTER 13 동시성
13.1 동시성 소개
13.2 병렬성
13.3 동시성
13.4 작업 스케줄러 유닛
13.5 프로세스와 스레드
13.6 발생 전 제약
13.7 동시성을 사용해야 하는 경우
13.8 공유 상태
13.9 마무리
CHAPTER 14 동기화
14.1 동시성 문제
14.2 고유한 동시성 문제
14.3 동기화 이후 문제
14.4 동기화 기술
14.5 스핀락
14.6 POSIX의 동시성
14.7 멀티프로세싱
14.8 멀티스레딩
14.9 마무리
CHAPTER 15 스레드 실행
15.1 스레드
15.2 POSIX 스레드
15.3 POSIX 스레드 스폰하기
15.4 경쟁 상태에 대한 예제
15.5 데이터 경쟁에 대한 예
15.6 마무리
CHAPTER 16 스레드 동기화
16.1 POSIX 동시성 제어
16.2 POSIX 스레드와 메모리
16.3 마무리
[PART VI 프로세스 간 통신]
CHAPTER 17 프로세스 실행
17.1 프로세스 실행 API
17.2 프로세스 실행 단계
17.3 공유 상태
17.4 멀티스레딩 대 멀티프로세싱
17.5 마무리
CHAPTER 18 프로세스 동기화
18.1 싱글 호스트 동시성 제어
18.2 기명 POSIX 세마포어
18.3 기명 뮤텍스
18.4 기명 조건 변수
18.5 분산된 동시성 제어
18.6 마무리
CHAPTER 19 싱글 호스트 IPC와 소켓
19.1 IPC 기법
19.2 통신 프로토콜
19.3 싱글 호스트 통신
19.4 소켓 프로그래밍
19.5 마무리
CHAPTER 20 소켓 프로그래밍
20.1 소켓 프로그래밍 복습
20.2 계산기 프로젝트
20.3 유닉스 도메인 소켓
20.4 네트워크 소켓
20.5 마무리
CHAPTER 21 다른 언어와의 통합
21.1 통합이 가능한 이유
21.2 필수 자료 획득하기
21.3 스택 라이브러리
21.4 C++과 통합하기
21.5 자바와 통합하기
21.6 파이썬과 통합하기
21.7 고와 통합하기
21.8 마무리
[PART VII 테스트와 유지 보수]
CHAPTER 22 유닛 테스트와 디버깅
22.1 소프트웨어 테스트
22.2 유닛 테스트
22.3 컴포넌트 테스트
22.4 C의 테스트 라이브러리
22.5 디버깅
22.6 마무리
CHAPTER 23 빌드 시스템
23.1 빌드 시스템 소개
23.2 메이크
23.3 CMake: 빌드 시스템이 아닙니다
23.4 닌자
23.5 바젤
23.6 빌드 시스템 비교하기
23.7 마무리
출판사리뷰
전문가로 발돋움하기 위한 C의 모든 것 파헤치기
C 전문가가 되고 싶은 개발자를 위해 실무에 유용한 예제와 실습을 모두 담았습니다. 프로그램을 작성할 때 유용한 C의 구성 요소부터 프로세스 메모리 구조, 스택과 힙, 유닉스의 역사, 최신 C의 새로운 기능, 테스트와 유지 보수 방법까지 설명합니다. C를 이용해 효율적인 프로그램을 작성하는 방법과 객체지향 원칙을 구현하는 방법, 프로세스 간 통신하는 방법도 소개합니다.
이 책은 C 개발자를 위한 훌륭한 책일 뿐만 아니라 컴퓨터가 실제로 어떻게 작동하는지 조금 더 깊이 파고들고 싶은 개발자에게도 유용합니다. 책을 읽으며 스스로 생각하고, 질문하고, 실습해보면서 탄탄한 기초를 가진 C 전문가로 성장해보세요. C의 가장 진보된 기능으로 떠나는 대장정을 마치고 나면, 소프트웨어 시스템을 더 넓은 관점에서 바라보는 더 나은 C 개발자가 될 것입니다.
대상 독자
C/C++ 프로그래밍 초급 과정을 이수한 학부생이나 주니어 엔지니어
현업에 C를 사용하는 개발자
공학이나 과학을 공부하는 학부생이나 연구원
필요 지식
컴퓨터 아키텍처 지식: 메모리, CPU, 주변 장치와 이들의 특성에 관한 내용
프로그래밍 기초 지식: 알고리듬, 이진수, 산술연산 등
프로그래밍 중급 지식: 조건문, 루프, 구조체, 클래스, 포인터, 함수에 관한 중급 지식
터미널과 셸 명령어 사용법
객체지향 프로그래밍 기초 지식(3부에서 객체지향을 자세히 다루지만 기초 지식이 있다면 내용을 이해하기가 수월합니다)
주요 내용
메모리 구조와 컴파일 파이프라인의 작동 방식과 최대 활용법
절차지향 C 코드에 객체지향 설계 원칙 적용하기
컴퓨터 시스템의 최대 성능을 끌어내는 저수준 코드 작성하기
동시성, 멀티프로세싱, 멀티프로세싱의 주요 개념
C++, 자바, 파이썬, 고(Go)에서 C 라이브러리 통합하기
유닛 테스트, 디버깅, 빌드 시스템으로 테스트 및 유지 보수하기
추천사
실무만으로 채울 수 없는 부분을 채워주는 책. 주니어에게 너무 좋은 책입니다.
강수연, 임베디드 소프트웨어 개발자
C의 기본 문법을 익힌 후에 C로 어떤 것을 할 수 있는지, 코드가 어떤 방식으로 작동하는지 자세히 안내하는 책입니다. 업무에 즉각적으로 도움이 되는 설명으로 가득 차 있습니다. 자세한 설명과 예제를 직접 실행해보며 코드가 작동 가능한 실행 파일로 생성되는 과정을 이해할 수 있었습니다. 특히 동시성을 다루는 5부에서는 단계별 작업을 코드 박스를 통해 세세하게 설명하고, 헷갈리는 용어와 개념도 자세히 설명해 명확하게 내용을 정리할 수 있었습니다. 또한 빌드 시스템에 대해서도 간략히 소개하며, 그 덕분에 실제로 프로젝트에 포함된 파일들이 어떤 역할을 하는지도 알 수 있었습니다. C 언어의 기본 문법을 익힌 후, 좀 더 빨리 이 책을 접했더라면 실력이 더 빨리 늘었을 거라 생각합니다.
권성민, 스마트레이더시스템 선임연구원
절차지향 프로그래밍 언어인 C 언어를 이용해 객체지향 프로그래밍을 시도하는 부분이 매우 흥미로웠습니다. C 언어는 객체지향이 될 수 없다는 것을 인정하고 시작하지만, 그럼에도 불구하고 이를 구현하기 위해 객체지향의 특성에서부터 세심하게 접근합니다. 그 결과 각 특성을 C 언어로 최대한 유사하게 구현했으며, 저 스스로도 객체지향 프로그래밍의 본질을 깊이 들여다볼 수 있는 기회였습니다. 그 외에도 C 언어를 이용해 심도 있는 다양한 주제를 제시하고 설명함으로써, 많은 C 언어 개발자에게 도전의 기회를 제공하는 책입니다.
박수빈, 엔씨소프트 개발자
C 프로그래밍 언어에 대한 매우 자세한 설명과 고급 활용법뿐만 아니라 컴파일 언어의 특징(컴파일러), 그리고 프로그램이 작성되는 운영체제를 포함해 광범위한 내용을 다루는 책입니다. 이 책에서 설명하는 내용은 다른 프로그래밍 언어를 사용할 때도 충분히 도움 되는 내용이며, 특히 C++을 주로 사용하고 있다면 반드시 읽어야 합니다.
사지원, 카카오모빌리티
C 언어를 오랫동안 사용한 개발자라도 이 책에서 다루는 다양한 지식을 익숙하게 사용하거나 모든 내용을 사용해본 개발자는 많지 않을 겁니다. 단순히 C 언어의 기능을 나열하는 것이 아닌, 실행 파일부터 메모리 구조, 테스트에 이르기까지 C 언어를 다루는 시니어 개발자에게 필요한 내용을 담았습니다. 그만큼 이 책은 전문성도 갖추고, 가독성도 훌륭한 완벽한 책입니다. 이 책은 C 언어 초중급 개발자를 전문가 수준으로 끌어올릴 수 있는 내용으로 가득 차 있습니다. 탄탄한 예제와 상세한 설명, 다양하지만 꼭 필요한 내용을 담아 C 언어 시니어 개발자가 될 수 있는 훌륭한 이정표 역할을 합니다. 지금까지 읽어본 많은 C 언어 도서 중 꼭 읽어야 할 필독서로 추천합니다.
손승하, 삼성전자
C++11만 사용하다가 이 책을 접하며 C 언어도 C11을 시작으로 모던(modern) C로 변화가 이루어지고 있다는 사실을 알게 되었습니다. 이 책을 읽으며 인상적이었던 부분은 C11 이후의 변화뿐만 아니라 C 언어의 특성과 활용을 좀 더 깊이 있게 다룬다는 점이었습니다. 예를 들면 C 언어를 C++과 비슷하게 사용하려면 어떻게 표현할 수 있는지, 소스 코드가 최종적으로 플랫폼에서 실행되기까지의 과정을 상세하게 설명합니다. C 언어는 다른 언어와 통합하기 쉬운 언어인데 이와 관련된 내용도 다루며 C 언어로 작성한 라이브러리를 다른 언어와 연동해보는 연습도 매우 유용했습니다. 모던 C뿐만 아니라 C 언어가 실행 파일로 변환되는 과정과 C++ 언어와의 비교 및 유사하게 사용하는 방법 그리고 표준 C 언어 등 다양한 주제를 생각해볼 수 있는 책이라 읽는 내내 도움이 많이 되었습니다.
1.프로그래머들이라면 C언어를 가장 먼저 접했을정도로 친숙하면서도 까탈스럽다고 느낄정도로 엄격한 언어이지만 디버깅을 통해 어떻게 프로그램 구동 및 동작 원리를 깨달을 수 있어 하며 주로 사용하는언어를 변경하더라도 크게 위화감이 없을 정도로 많은 도움이 된다. 특히 해당 서적은 C를 어떻게 하면 더 고급스럽게 프로그래밍할 수 있을지 다른 언어와 병합해서 효율을 줄 수 있을 지 등 아직까지C언어가 건재하다는 것을 볼 수 있었다.
부제: "동시성, OOP부터 최신 C, 고급 기능까지! 극한의 C를 마주하려는 여행자를 위한 가이드북"
C 언어를 배울 때 교재로 접했던 책은 300페이지가 조금 안되는 'C Programming Language'라는 얇은 책이었는데 이 책은 900페이지가 넘어갑니다. 어떤 내용을 담고 있기에 이렇게 두꺼울까요? 새로운 문법이 많이 추가된 것일까요?
'전문가를 위한 C'는 C 언어를 중심으로 프로그래밍 언어, 컴퓨터 아키텍처에 대한 지식을 설명하는 내용이 많습니다. 특히, C 언어에 존재하는 개념만을 설명하지 않고, C 언어에 없는 개념들도 설명합니다. 예를 들면 C 언어로 객체지향을 설명하는 부분이 있습니다.
C 언어로 새로운 C++을 만들려는 것이 아닙니다. 그보다는 C가 어떻게 OOP를 사용할 수 있는 가능성을 가지는지 짐작해보려고 합니다.
객체지향과 거리가 먼 언어인 C 언어로 객체지향의 핵심요소들인 합성(Composition), 집합(Aggregation), 확장(Extension), 상속(Inheritance)을 이해하기 좋게 설명해주는 부분이 특히 인상깊었습니다. 프로그래밍 언어, 컴퓨터 아키텍처에 대한 개념을 간단하게 설명하고, 상세한 내용을 찾아볼 수 있도록 관련 링크를 제공하고 있어 이 책을 시작으로 개발에 대한 지식을 확장해나가는 것도 좋을 것 같습니다. (이 책을 잘 활용하는 방법 중 하나가 아닐가 하네요.)
책의 대상 독자는 C/C++ 주니어와 중급 엔지니어라고 합니다. 어느정도 수준의 지식을 가지고 있어야 이 책을 읽을 수 있을까요? 서문에 책을 읽기 위한 최소한의 요구사항이 정리되어 있습니다.
1. 컴퓨터 아키텍처 지식
2. 프로그래밍 기초 지식
3. 터미널과 셀 명령어 사용법
4. 프로그래밍 중급 지식
5. 객체지향 프로그래밍 기초 지식
최소한의 요구사항이 저 정도라면 이 책은 쉬운 책은 아닙니다. 깊이있는 지식을 원하는 분들에게 적합한 책입니다. C 언어의 문법을 익혀서 빠르게 개발을 시작하려는 분들에게는 맞지 않을 수도 있습니다. C 언어를 시작으로 개발에 대한 전반적인 지식을 탄탄하게 쌓아가고자하는 분들에게 추천합니다.
이해하기가 쉬운 책입니다. 처음 C를 공부하는데 도움이 무척 될거에요!!
전문가를 위한 C 책은 C 언어를 처음 접하는 사람도 바이블로 볼 수 있는 친절한 책이다. 900p가 넘는 내용이 꽉찬 책인데, 기본에 충실함이 묻어나오는 책이다. 이해하기 쉽게 잘 설명되어 있는게 장점.
C 를 어떤걸 바이블로 봐야할까 고민된다면 이 책 읽어보자.
학교 수업이나 기타 개인적인 공부로 C언어를 공부했었는데. 정말 아는 것이 하나도 없었다는 것을 알게되는 겸손함을 주는 책이다.
이 책은 프로그래밍 언어 C의 기초부터 심화적인 내용까지 폭넓게 다루며, C 언어의 동작 방식과 이를 이용한 최적화 기법, 메모리 관리, 시스템 프로그래밍 등 C 언어의 전반적인 개념과 응용에 대한 이해를 돕는다.
특이하게도 기본서에 적혀있을 내용이 빠지거나 적은데 900페이지 가까이 되는 책이 나왔다는 것은 놀라운 일이다.
이 책은 C 프로그래밍 경험이 '많이' 있는 전문가들을 대상으로 작성되었기 때문에, 초보자들이 이해하기 어렵거나 생소한 내용들이 존재할 수 있다. 그러나, C 언어에 대한 기초 지식이 있다면 이 책을 통해 보다 깊이있는 이해와 함께 더욱 전문적인 지식을 습득할 수 있을 것이다. 이 책의 강점은 바로 그 깊이 있는 내용과 설명이다.
저자는 C 언어의 기본적인 개념부터 시작해, 포인터, 함수, 배열, 구조체, 비트 연산, 동기화 기법, 메모리 관리 등에 이르기까지 폭넓게 다룬다. 이러한 내용은 C 프로그래밍에 있어서 굉장히 중요한 부분이며, C를 전문적으로 다루기 위해서는 반드시 이러한 내용들을 숙지해야 한다. 이 책은 이러한 내용들을 상세하게 다룬다.
이 책은 초보자들을 대상으로 작성되지 않았기 때문에, C 언어에 대한 지식이 없는 독자들은 이해하기 어려울 수 있다. 또한, 이 책은 C 언어에 대한 기본적인 개념을 다루는 부분에서는 매우 상세한 설명을 하지만, 일부 심화 내용들에 대해서는 설명이 부족한 경우가 있다. 이 부분들은 추가적인 참고 자료를 통해 보충해야 할 필요가 있다.
하지만, 이 책은 C 언어를 전문적으로 다루는 데 있어서 매우 중요한 지식과 정보들을 담고 있기 때문에, C 언어를 이해하고 전문적으로 다루고 싶은 개발자들에게는 반드시 추천할 만한 서적이다. 이 책을 통해 C 언어에 대한 전문적인 지식과 실무에서 유용한 최적화 기법들을 습득할 수 있을 것이다.
2023년에 C언어가 가지는 의미는 무엇일까? C언어는 절차적 프로그래밍 언어의 맹주인 1972년생 프로그래밍 언어이지만, 객체지향을 넘어 함수형 프로그래밍이라는 패러다임이 몰아치는 현 시기에 C언어는 어떤 가치와 지향을 가지고 개발자들에게 다가설 수 있을까? 물론 나야 C/C++계열의 언어를 가장 좋아하고 있지만, 이제는 다른 신생 모던(Modern) 언어들이 제공하는 문제인식 개념이나 편의성을 C언어는 어떻게 풀어내려고 접근하고 있을까? 하는 궁금점을 가지고 모던 C언어를 살펴보기 위해 이 책을 골랐다.
이 책의 제목은 '전문가를 위한C'라고 번역되었고, 두께가 무려 900여 페이지에 달할 만큼 위압감을 주는 책이다. 원서의 제목은 "Extream C"이다. C언어 역시 짝꿍 C++와 함께 발전을 거듭해왔다. C언어는 1989년 ANSI C 스펙이 확정된 이후에도 C95, 99, 11, 18을 넘어 23까지 발전을 해오고 있지만, 그닥 개발자 그룹의 많은 관심을 받지는 못했다. 전문가들이 보아야할 책으로 생각할수도 있겠지만, 이 책을 80% 정도 읽은 시점에서 나는 초급을 벗어난, 고급 개발자가 되고 싶은 컴파일러 방식의 언어 중급 개발자들에게 큰 도움이 될 수 있는 책이라 본다. 단순히 C언어 문법을 익히고자 한다면 이 책은 그 답이 아닐 가능성이 높다.
이 책은 크게 7부로 나뉘어진다.
1부와 2부는 컴파일러 언어인 C를 중심으로 어떻게 컴파일러가 실행파일을 만들어 가는지, 실행파일은 기본적으로 어떻게 동작하는지를 설명한다. 특히 4장 에서는 C코드가 목적파일을 거쳐 실행파일까지 변환되는 과정속에서 메모리/데이터가 어떤 식으로 펼쳐지는지를 소개한다.왜 스택과 힙이 있는지를 잘 설명하고 있고, 각 메모리 세그먼트의 역할과 분석 방법을 통해 C코드의 동작원리를 설명한다. 윈도우가 아니라 맥/리눅스를 중심으로 소개하는데에서 한때 윈도우 프로그래밍하면 C였던 시대가 아련하게 느껴졌다.
3부에서는 재미있게도 C언어이지만 객체지향이라는 개념을 다룬다. 사실 C언어에서도 객체지향이 가능하다. 다만 조금 불편할 뿐이지.. 저자는 OOP를 언어의 특징이 아니라 "문제를 생각하고 분석하는 방식"(P.254)으로 설명하면서 C와 C++의 관계까지 소개하고 있다.
4부에서는 유닉스를 소개하면서 커널와 사용자 모드에 대해 설명한다. 다시한번 윈도우에서 길을 잃은 C언어의 모습이 느껴져 시대의 변화가 느껴지기도 한다. 하지만 C가 여전히 임베디드 시장이나 게임엔진, 하드코어 영역에서 중요한 역할을 맡고 있구나 하는 생각도 든다.
5부와 6부는 모든 언어에서 화두가 되는 동시성/병렬성과 프로세스간 통신의 방법을 소개한다. 꽤 많은 분량을 할애하여 쓰레드 동기화 및 IPC, 소켓 통신을 다룬다. 다만 언어 설명서와 같이 아주 상세하게 다루지는 않는다.
7부는 테스트와 빌드시스템 이야기인데, 소프트웨어의 유지 보수 이야기라면 모듈 패키지 관리 솔루션인 vcpkg나 conan에 대한 설명까지 곁들여졌으면 더 좋을 것 같다.
이 책은 전체적으로 초/중급 개발자(초년~5년차) 정도의 개발자들이 개발의 경험을 바탕으로 지식을 좀 더 깊게 만들때 도움이 될만한 책이라 생각한다. 단순히 C언어 책으로 인식되기엔 아깝고, 컴파일러 언어를 사용하는 개발자라면 한번씩 읽으면서 C가 만들어내는 방식을 이해해 보는 것도 유용하리라 생각한다. 윈도우 프로그래밍과 관련해서는 다른 책을 더 읽어야 한다. 이 책은 그런 내용을 다루지는 않는다.
해당 책은 C와 C++ 개발에 관해 최소한의 지식을 가진 독자를 위해 썼습니다. 주니어와 중급 엔지니어가 주요 독자인데, 이 정도 지식이라면 이 책을 최대한 활용할 수 있다고 이야기를 해주고 있습니다. 각 부에서는 C 프로그래미의 특정 측면에 대해 이야기를 하는데, 1부에서는 C 프로젝트 빌드 방법, 2부에서는 메모리, 3부에서는 객체지향에 초점을 맞춰 설명을 해줍니다.
이후 4부에서는 유닉스와 C의 관계에 대해 살펴보고, 5부에서는 동시성, 6부에서는 프로세스 간 통신을 다루며, 마지막으로 7부에서는 테스트 및 유지 보수에 대해 다룹니다. 지금까지 보시면 알겠지만, 사실 C 언어에 대하여 최소한의 지식의 조건이 과연 이 정도 수준일까? 싶을 정도로 높게 잡혀있다고 개인적으로 생각이 듭니다.
컴퓨터 아키텍처 지식 및 프로그래밍 기초 지식, 터미널과 셸 명령어 사용법, 프로그래밍 중급 지식, 마지막으로 객체 지향 프로그래밍 기초 지식 까지에 대해 알고 있어야 이 책을 읽을 수 있다고 이야기를 합니다. 그렇다보니 갓 C언어 기초를 떼신 분들일지라도 현업자가 아닐 경우 책을 대하기에 조금 어려울 수 있겠다고 느껴졌습니다.
특히 간단한 문법에 대해 다루는 것이 아닌 프로젝트 빌드 방법부터 접근하여, 전처리기 활용 방법이나 OOP 등 기초 책에서는 잘 다루지 않는 내용에 대해 자주 언급되고 있습니다. 영문 책 제목이 Extreme C 라고 하는데, 확실히 책의 깊이나 두께에서 C언어를 극한으로 다루길 원하시는 분들을 위한 책이라고 느껴졌습니다.
결론은, 임베디드 분야 등 C언어를 활용하여 실용적인 측면으로 다룰 줄 아시는 분들이 읽으신다면 재미있게 읽으시겠지만, C언어를 한번 마친 후 접근하시려는 분들께는 꽤 어려운 벽이 될 수 있겠단 생각이 듭니다. 그만큼 타겟층이 명확하기 때문에, C언어 자체에 대해 배우기 보다는 C를 주로 활용하는 시스템 프로그래밍 책이라고 이해하시는 편이 좋겠습니다.
개발에 있어서 기본은 무엇보다 중요합니다. 기본이 흔들리거나 없다면 정말 정말 큰 프로젝트를 할 경우에 무너지는 건 한순간입니다. 아주 사소하지만 중요한 포인트를 놓쳐서 일을 그르치는 경우를 많이 봤습니다. '전문가를 위한 C'란 책을 읽으면서 마음 한편으로 기본이 항상 중요하단 생각이 문득문득 드네요.
C는 시스템 프로그래밍과 임베디드 시스템 등 다양한 분야에서 사용되는 프로그래밍 언어입니다. 지금은 다들 자바, 자바스크립트, 코틀린 등 여러 현대 언어들을 쓰지만 그 모든 것들의 할아버지 격인 언어인 C는 아직도 현업에서 쌩쌩하게 사용되고 있는 정말 최장수 언어이기도 합니다.
기본적인 C 학습에는 다음과 같은 부분들을 공부하는게 기본이 됩니다.
C 언어의 기본 문법과 표준 라이브러리의 이해 : C 언어의 문법을 이해하고 사용하는 것은 매우 중요합니다. 이를 위해 변수, 연산자, 제어문, 함수 등에 대한 이해와 사용법을 학습해야 합니다. 또한 표준 라이브러리 함수를 이해하고 활용할 수 있어야 합니다. 여기에 책에서 언급한 최신 C의 경우는 값을 반환하지 않는 함수라던가 익명 구조체와 익명 공용체, 멀티스레딩 등 이전과 달라지고 개선된 부분들이 꽤 있습니다.
포인터의 이해 : C는 메모리를 직접 조작할 수 있는 언어이기 때문에 C 언어에서 포인터는 중요한 개념 중 하나입니다. 포인터는 메모리 주소를 가리키는 변수로서, 동적 메모리 할당과 같은 메모리 작업을 수행하는 데 필요합니다. 포인터 연산과 포인터를 사용한 데이터 구조의 구현 등을 학습해야 합니다. 더불어서 책에 나온 허상포인터까지 알게 된다면 더 좋죠.
메모리 관리의 이해 : C 언어에서 메모리를 효율적으로 관리하는 것은 중요합니다. 동적 메모리 할당과 해제, 메모리 누수 방지, 스택과 힙 메모리의 차이 등을 이해하고 사용해야 합니다. 좀 더 나아가면 BSS, 데이터, 텍스트 세그먼트의 정적 메모리 레이아웃, 동적 메모리 레이아웃의 프로세스 메모리 구조를 이해하면 좋습니다.
파일 입출력 : C 언어에서 파일 입출력을 다루는 방법을 학습해야 합니다. 파일 읽기, 쓰기, 열기, 닫기 등의 함수를 이해하고 사용할 수 있어야 합니다.
네트워크 프로그래밍의 이해 : 파일 입출력에 이해하다 보면 자연스럽게 네트워크로 넘어가게 됩니다. 소켓 프로그래밍과 TCP, UDP, 네트워크 계층에 대해 공부해야 합니다.
프로그램 구조 : 대규모 C 언어 프로그램을 작성하기 위해서는 코드의 구조화와 모듈화가 필요합니다. 이를 위해 함수, 구조체, 열거형, 헤더 파일 등을 사용하는 방법을 학습해야 합니다.
디버깅 : C 언어 프로그램에서 버그를 찾고 해결하는 능력은 매우 중요합니다. gdb와 같은 디버깅 도구를 사용하는 방법과 디버깅 기술 등을 학습해야 합니다.
프로그래밍 패러다임 : C 언어는 절차지향적인 프로그래밍 언어입니다. 그러나 객체지향적인 코드를 작성하는 방법을 이해하고 사용할 수 있어야 합니다. 함수형 프로그래밍 또한 C 언어에서 사용할 수 있습니다. OOP와 캡슐화를 쓰려면 면 객체지향 사고를 해야하는데 제 경우는 이 부분이 좀 어렵더군요. 상속과 다형성, 합성과 집합. 추상화 등 자주 쓰지 않으면 항상 헷갈리는 개념들입니다.
컴파일러 최적화 : 컴파일러 최적화를 배우면 메모리 사이즈나 프로그램의 속도를 향상 시킬 수 있습니다.
그 외에도 책에 정말 많은 내용들이 나와있어서 필요할 때마다 찾아보기 참 좋은 책이네요. 물론 텍스트와 두꺼운 분량은 가볍게 소설처럼 읽기에는 무리가 있지만요.
프로그래밍 책들을 보면, 많은 책들이 입문자 또는 초보자를 위한 책들이 많다보니, 특정 언어에 어느 정도 익숙해 진 중급자 이상에게 맞는 책들을 쉽게 찾기는 어렵다. 특히 C 언어는 나온지 40년이 넘었었지만 여전히 많이 사용되고 있다. 하지만 깊이 있는 내용들은 여러 분야의 내용들에 내용들이 흩어져 있어 하나의 C 책에 내용들이 집약된 책을 찾아보기는 어렵다. 그래서 “전문가 위한 C”를 보았을 때, 이 책은 어떨까 하는 기대를 가지고 책을 읽기 시작했다.
우선 책 목차를 먼저 보았을 때, 웬지 시스템 프로그래밍과 유사하지만 또 좀 다른 구성으로 되어 있어 어디부터 먼저 읽어볼까 하는 감이 서지 않아 처음부터 정독을 해 나갔다. 책을 다 읽고 나서(900페이지가 넘는 전문 서적을 다 읽어내는 게 쉽지 않았다) 이 책에 대해서 생각이 드는 건 다양한 주제들을 조금씩이나마 하나씩 건드려보는 책 같은 느낌이었다. 그러다보니 책을 읽는 분들의 대상이 좀 애매하다는 느낌이 든다. 책의 내용이 C 언어를 전혀 모르고서는 읽을 수 없는 책이면서, 또 여러 분야를 어느 정도 접해본 독자에게는 한번쯤은 접했을 법한 내용들로 이루어져 있어, 어떤 독자가 대상인지 잘 모르겠다는 것이 솔직한 심정이다.
그렇다고 이 책의 내용이 안 좋거나 번역 수준이 나쁘다는 의미는 아니다. 책을 읽어보면 알겠지만 책의 저자는 다양한 분야에서 많은 경험을 하였다는 느낌이 들었드며, 책 번역 역시 읽는 데 부자연스러운 부분을 찾기 힘들정도로 잘 되어 있다.
C 언어를 처음 배울 때 멋모르고 hello world 부터 출력하면서 감을 익혀나가면서 하나 하나 더 많은 내용을 배운 것처럼 이 책의 내용도 그런 식으로 설명이 되어 있어 꼼꼼히 책을 읽어나가면, 충분히 이해할 수 있도록 설명이 차근차근 되어 있다. 하지만 다양한 내용이 있다보니, 이게 나에게 필요한 건가? 이게 실제 업무에 사용될까? 하는 생각을 책을 읽으면서 하게 된다는 점이다.
우선 책을 읽으면서 좋았다고 생각하는 부분부터 작성해 보겠다. 이 책에서 저자가 설명하는 내용에 대한 예제나 유틸리티는 챕터마다 조금씩 다르지만 유닉스 기반 환경에서 테스트를 해 볼 수 있도록 되어 있는데, 대부분의 개인 개발자가 요즘 쉽게 접할 수 있는 Linux 환경과 MacOS 환경에서 시험할 수 있도록 되어 있다. 직접 Typing을 해 볼 수도 있겠지만, 저자가 이미 github에 올려둔 예제를 다운로드 받아, cmake와 make를 가지고 컴파일해 쉽게 결과를 체크해 볼 수 있다. 보통 특정 환경 하나만을 가정하여 설명을 하지만, 서로 다른 두 시스템에서 동일하게 동작하는 부분, 서로 다르게 동작하는 부분을 각각 설명하고 있는 부분은 이 책의 장점이라는 생각이 든다. 물론 이 때문에 책이 좀 두꺼운 것은 책의 단점? 이라고 생각을 해야할 지 모르겠지만… ^^
특히 책의 앞쪽에서는 OS간 유틸리티의 차이점, 파일 포맷의 차이점 등에서 차이를 보여주는 부분들이 있지만, 책의 중 후반부에 다다르면 library(예: pthread) 에서 지원하는 기능 유무가 달라져, OS 별로 다르게 동작할 수 있는 부분에 대해 직접 코드를 구현해서 설명을 하고 있어, MacOS 환경에서 이 책을 시험해 보는 독자에 대한 배려도 눈에 띈다.
또 책의 처음 시작부터 전처리 과정, compile 단계 및 link 처리 과정에 대한 내용을 단계 별로 설명해 둔 부분이 있어, 단순히 언어를 배우고 이용하는 단계에서 잘 들여다볼 일이 없는 부분에 대해서도 다루고 있어, 언어에 대해 조금 더 깊은 이해를 할 수 있다는 점이 마음에 들었다. 단 해당 부분의 내용이 좀 더 깊었으면 했지만 그렇지 못한 부분이 아쉽기는 하다.
다른 책에서 찾아보기 힘든 부분 중 하나로 책 후반부에 있는 “다른 언어와의 통합” 부분은 개발자가 C로 모든 프로젝트를 진행하거나 C로 기술된 라이브러리만 사용하는 경우가 아니라면 한번쯤은 마주치는 이슈이다. 특히나 C++과의 통합은 생각보다 많이 이루어진다. 경험이 없는 경우, 컴파일 단계를 넘어가더라도 link 시 문제가 많이 발생하고 또 디버깅 시 C++의 맹글링 특성으로 인해 애를 먹는 경우도 자주 발생하게 된다. 그래서 이러한 일을 해야하는 개발자들에게 많은 도움이 되는 부분인데, C++말고도 다른 언어를 다루어주는 부분이 사실 더 반갑게 여겨졌다. Java나 Python 그리고 Go와 같은 C나 C++의 통합보다 더 많은 작업을 해야하는 언어들에 대해서 쉬운 tutorial 형식으로 내용을 알려주기 때문에 이를 응용해 더 복잡한 내용도 응용할 수 있어 업무에도 도움이 될 것이라 생각한다.
많은 내용은 아니지만 꼭 필요한 유닛 테스트와 많이 사용되는 일부 framework을 이용한 예제는 개발 시 사용해보지 않은 분들에게는 좋은 도입부가 될 수 있을 것이라 생각한다. 이 책을 읽는 분들의 실력이라면 이미 다 사용하고 계시겠지만, 만약 그렇지 않은 분들이라면 많은 도움이 될 것이라 생각된다. 이 책에서는 분량이 너무 적게 나와있기 때문에 필요시 책에서 소개한 framework site를 참고하면 더 많은 내용을 익힐 수 있을 것이라 생각한다.
책 마지막에 단순한 부록이 아닌 빌드시스템이 한 챕터로 할당되어 기술되어 있는 부분도 이 책의 장점이라 생각한다 특히 make나 cmake 뿐만이 아닌 ninja나 Bazel도 간단하지만 사용법이 기술되어 있어, 필요한 분들이 쉽게 접근하기에 알맞을 것으로 생각된다.
다음은 개인적으로 아쉽다고 생각한 부분을 한 두가지 뽑아본 것으로 이 부분은 책을 읽으신 분들에 따라 생각이 다를 수 있을 것 같다.
1. OOS
C와 같은 절차적 언어를 이용해 OOP에 대해 다루는 부분은 다른 책들에서는 많이 다루지 않는 부분이라 신선한 부분이라 생각했다. OOP가 가지는 개념적인 부분을 구현하면서 개념을 C를 이용해 구현을 하고, 이를 눈으로 확인함으로써 어떻게 동작하는지 확인을 하는 것은 한번쯤은 배워볼만한 내용이라고 생각이 든다. 하지만 실제 C로 코딩 시 이렇게 사용을 하게 될까? 라는 생각이 관련 챕터를 읽는 동안 든 생각이다. 현재 C로만 코딩을 해야하는 시스템에서는 유용할 수도 있겠지만, 반드시 그런 제약이 아니라면, 굳이 C++을 두고 힘들게 C로 코딩하지는 않을 것 같다. 단순히 이렇게 동작하는구나 정도만 보고 넘어가면 될 것 같다는 생각이 드는 부분인데 생각보다 많은 챕터를 할애할 필요가 있었을까? 하는 생각이 들었다.
2. 유닉스
리눅스 시스템 프로그래밍 관련 서적들이나 특정 분야에 대해 작성된 책들이 가지고 있는 깊이 있는 주제들과 중복되는 내용이다. 유닉스 시스템의 역사와 C 언어가 무관하지 않으니 이 내용을 다루고 있기는 하지만 굳이 여기서 다루어야 했을까? 라는 생각이 계속 들었다. CPU protection ring, syscall 작성 및 커널 빌드, 커널의 아키텍쳐 구분, kernel module 작성 등은 C 언어 책 보다는 OS 책 특히나 Linux OS 책에서 다루어야 할 부분이라고 생각한다.
가능한한 많은 내용을 독자에게 전달하려고 쓰여진 이 방대한 책에 대해 개인적으로 생각하는 장점 및 단점을 기술했지만, 이 책은 C언어로 많은 내용을 경험해 보지 못한 분들은 반드시 한 번은 읽어볼 내용이라 생각이 든다. 이 책을 읽고나서 정말로 Extream한 내용을 살펴보기 원하는 독자라면 개인적으로 국내서에만 매달리지 말고 해외 원서도 찾아보는 것을 추천하고 싶다.
리뷰 초반에도 언급했지만, 전에는 이러한 책이 별로 없다보니, 각 분야별로 책을 각각 여러 권 사서 읽어야 했고, 그러면서도 설명이 부족한 부분에 많은 시간을 할애해야했지만, 이 책은 그러한 간격을 줄여주는 역할을 충분히 할 수 있다고 생각한다.
책을 처음 접하고, 목차를 보고 전문가를 위한 책이란 느낌을 받았다. 보통의 책에는 C언어 기초 문법이 들어 있기 마련인데 독자 대상이 수준을 요구하는 책이다 보니 이런 내용은 없다. 오랜기간 동안 프로그래머로 살아 오다 보니, 가끔은 타 언어와 연동을 통한 프로그램을 개발하는 일들을 만나게 되었다. 이 도서(ch 21, 다른 언어와의 통합)에는 아주 좋은 예시를 제공하고 있다. 최근 파이썬이과 Golang이 많이 사용되고 있는 점을 감안한다면, low-level을 요구하는 부분은 C로 개발하고 상위단은 사용의 편리함이나 메모리 관리를 제공하는 프로그래밍 언어로 사용하는 통합 개발이 가능하다. 이러한 부분은 쉽게 접할 수 없는 부분인데, 이 책에는 훌륭한 예제를 제공하고 있다.
이를 통해 중급에서 고급 이상으로 개발 능력을 높일 수 있고, 특히나 연구 분야에서 다양한 프로그래밍 언어가 제공하는 기능을 통합하여 개발할 수 있어 최적의 솔루션을 얻을 수 있다. 책을 리뷰하면서 제일 관심이 많았던 부분이라 여기에 대한 리뷰를 올리며, 많은 개발자분들께 도움되는 책이라 추천하고 싶다.
거두절미하고, 이 책에 대해 평하기 전에 현 시점에 C언어를 공부하는 것이 의미가 있는가를 얘기해 보고자 합니다. Java 언어를 필두로 더 이상 메모리에 직접 접근하고, OS나 기기 자체의 기능을 사용하는 일은 프로그래밍 언어 단에서는 할 일이 없어지고 있고, 애당초 개발자가 C 언어를 직접 사용할 만한 일이 없는 게 사실이니까요. C 언어를 쓸 일이 없는데 C 언어 책이라니? 이 책의 내용이 어떻든, 훌륭하던 별로 던 간에 이 부분은 먼저 짚어볼 만해 보입니다.
최근 가장 핫 한 프로그래밍 언어라면, 그 중 하나로 파이썬을 꼽는데 이견이 있는 분은 많지 않을 듯합니다. 조금 과장하자면 C언어의 안티테제(Antithese) 라고 해도 될 정도로 C 언어와는 지향점이 다른 언어 고, C 언어보다 배우기 쉽고, 쓰기 편하죠. 하지만 그 파이썬(정확히는 CPython 인터프리터)는 C 언어로 만들어졌고, 대부분의 파이썬 기본 라이브러리들은 파이썬이 아닌 C 언어로 작성되어 있습니다. 뿐만 아니라 유명한 파이썬 패키지들의 대부분이 C 혹은 C++ 언어로 작성된 Extension에 기반하고 있기도 합니다. Node.js 는 어떨까요? 파이썬과 마찬가지로 NPM의 수많은 유명 패키지들이 C/C++ 언어로 작성된 Native Module을 활용하여 구현되어 있습니다. Java 언어는 어떨까요? JNI(Java Native Interface)나 안드로이드의 NDK(Native Development Kit)를 활용해 만들어진 수많은 오픈소스들이 있습니다.
보다시피 어떤 최신의 하이레벨 프로그레밍 언어 든, 나온 지 수십년이 지난 C 언어와의 상호운용성(interoperability)이 유지되고 있는 것을 알 수 있는데, 이는 최근에 나온 언어를 사용하더라도 오픈소스를 활용하거나, 보다 깊이 있게 파고들다 보면 소소하게는 C 언어로 작성된 코드의 컴파일 같은, C 언어에 대한 이해가 요구되는 시점이 반드시 오게 된다는 것을 의미합니다. 그렇습니다. 나온 지 수십년이 지난 오래된 프로그래밍 언어이지만 여전히 공부해야 한다는 것이죠.
아, 이 책의 내용이요? 원제 대로 그야말로 익스트림, C 언어의 극한까지 다루고 있습니다. C언어를 다루는 데 필요한 모든 내용이 있다고 해도 과언이 아니었습니다. 무엇을 기대하던 그 이상을 보여줄 것이라 생각됩니다.
처음 프로그래밍을 배울 때만 해도 어떤 언어를 배우든 C언어가 가장 기초가 된다는 이야기를 많이 들었던 것 같다. 물론 첫 언어에 정답이 있다고 생각하지는 않는다. 다만 나는 C언어가 프로그래밍 언어의 발전의 중심에 있었으며, 하드웨어, 운영체제와 가까운 만큼 배울 점이 많은 언어라고 생각한다. 그리고 C언어는 만들어진지 이제 50년이 되었지만 아직도 많은 프로젝트에서 사용된다.
"전문가를 위한 C"라는 제목처럼 이 책은 초심자를 위한 책은 아니다. 처음 C 언어를 배운다면 쉬우면서 사람들이 많이 읽은 책을 읽고, 그 다음 더 깊이있는 책을 읽어야 한다고 생각한다. 이 책은 두 번째나 세 번째 C언어 책으로 좋은 것 같다. 다른 책으로는 이 책도 추천한다. 물론 단순히 나의 추천이다. 언어의 학습에 있어 절대적인 순서나 무조건 읽어야 할 책은 없다.
이 책은 크게 컴파일 과정, 목적 파일의 형식, 메모리 레이아웃, 객체지향, 유닉스, 최신 C, 동시성, 소켓, 프로세스간 통신 등의 다양한 주제를 심도있게 다룬다. 그 중 일부 내용을 정리해보았다. 읽어보고 흥미가 생긴다면 일독을 권한다.
프로젝트 빌드
이 챕터에서는 C언어 소스와 헤더파일이 실행 파일이 되기까지의 과정 다룬다. 다만 단순히 "전처리기 -> 컴파일러 -> 어셈블러 -> 링커를 거쳐서 실행 파일이 된다"고 끝내지 않고, 조금 더 심도있게 다룬다.
소스코드는 전처리기를 거쳐 변환 단위 (또는 컴파일 단위)가 되며, 이는 컴파일러 프론트엔드가 렉서와 파서를 거쳐 추상 구문 트리 (AST)라는 구조로 변환한다. 그 다음 컴파일러는 이를 어셈블리와 유사하지만 하드웨어에 독립적인 중간 표현 (LLVM IR)으로 변환한 후, 하드웨어에 맞는 어셈블리로 번역한다. 어셈블리는 하드웨어 벤더사에서 제공하는 (또는 오픈소스인) 어셈블러를 거쳐 프로세서가 해석할 수 있는 기계어를 포함하는 재배치 가능한목적 파일이 된다.
우리의 목표는 프로젝트 전체를 빌드하는 것이지만 컴파일러가 하는 일은 하나의 변환 단위를 재배치 가능한목적 파일로 만드는 것이다. 재배치 가능한 목적 파일은 그 자체로 실행하기에는 부족한 정보가 많기 때문에 대체로 최종 결과물이 아니라 중간 단계이다.
예를 들어 우리가 foo.c에 foo()라는 함수를 정의하고 main.c에서 foo()를 호출한다고 해보자. 전처리기를 거쳐 foo.c와 main.c는 서로 다른 변환 단위가 되며, 변환 단위 바깥에 정의된 함수의 위치는 알지 못한다. 따라서 컴파일러는 main.o에 foo()를 호출하는 명령어는 삽입하지만, 호출되는 함수의 실제 주소 (심볼) 는 링커가 목적 파일들을 합치면서 결정한다. 링커는 목적 파일들을 엮어서 최종적으로 실행 가능한 목적 파일을 구성한다.
목적 파일
소프트웨어는 언어에만 국한되지 않는다. C언어를 잘 다루려면 C언어가 컴파일되는 과정에 대해서도 잘 알아야 한다. 이 챕터에서는 그 중 목적 파일의 형식에 관해 자세히 다룬다.
ABI와 API
API (Application Programming Interface)는 많이 들어본 말인데 라이브러리 등에서 프로그램의 개발을 위해 제공하는 프로그래밍 인터페이스이다. 라이브러리를 사용하는 쪽에서는 인터페이스를 정해진 규칙에 따라서 사용해야 하며, 사용자는 인터페이스 뒤에서 무슨 일이 일어나는지는 몰라도 된다. 대신 정해진 규칙만 잘 따른다면 문제 없이 라이브러리에서 제공하는 기능을 사용할 수 있다.
이와 유사하게 서로 다른 환경에서 빌드된 목적 파일들(예를 들어 libc와 내가 작성한 프로그램)을 함께 사용하려면 규칙이 필요하다. 이러한 규칙을 ABI (Application Binary Interface)라고 한다.
ABI는 보통 명령어 집합, 함수 호출 규약, 시스템 호출 방식, 목적 파일의 형식 등을 정의한다. 리눅스나 BSD 등의 유닉스 계열 시스템에서는 System V ABI를 사용한다. ELF (Executable and Linking Format)는 System V ABI에서 사용되는 표준 목적 파일 형식이다.
목적 파일의 형식
프로세서가 사용하는 명령어 셋에 따라서 목적 파일에 사용되는 명령어들은 매우 다르지만, 목적 파일의 구조 자체는 프로세서의 아키텍처와는 독립적이다.
재배치 가능한 목적 파일은 최종 위에서 설명했듯 변환 단위가 컴파일러와 어셈블러를 거친 이후의 결과물이다. 재배치 가능한 목적 파일은 변환 단위에서 선언된 함수와 전역변수, 심벌에 대한 정보를 포함한다.
그런데 목적 파일이면 목적 파일이지 재배치 가능한 목적 파일은 뭐고, 실행 가능한 목적 파일은 어떻게 다른가? 재배치 가능한 이라는 말은 말 그대로 명령어의 주소가 결정되지 않고 목적 파일들을 합치는 순서에 따라서 바뀔 수 있음을 의미한다. 주소가 아직 결정되지 않았기 때문에 실행이 불가능하다.
링커는 재배치 가능한 목적 파일들을 합치면서 심볼들의 주소를 결정하고 실행 가능한 목적 파일을 만들어낸다.
책 마지막 장에찍힌 페이지 번호는 912. 거의 천 페이지에 이르는 아주 두꺼운 책이다. 원서의 제목은 “Extreme C”. 이를 번역한 우리말 책 제목은“전문가를 위한 C”로 다소 순화된 자세를 취하고 있지만, 책의 두께와 검은 색의 디자인만으로도 매우 강렬한 첫인상의 책이다.
C 언어가 얼마나 인기있고, 많이 쓰이는지는 다른 책에 대한 리뷰에서도TIOBE Index를 이용하여 언급한 바가 있다. C 언어의역사에 대해 이야기를 할 때면, 1972년도와 유닉스를 언급하게 된다.처음 C 언어가 세상에 나온지도 벌써 50년이넘었고, C 언어 이후로 Java, C# 등 다양한 언어가만들어졌음에도 여전히 활발하게 사용되고 있는 것을 보면 놀라움을 금치 않을 수 없다. 컴퓨터의 운영체제를보다 쉽게 만들기 위해 만들어졌던 언어였던만큼 메모리 등 하드웨어를 다루는 강력한 방법을 가진 C는일반적인 어플리케이션 뿐만 아니라 임베디드 시스템에서는 거의 필수적으로 사용되고 있다.
“전문가를 위한 C” 는 이렇듯 널리 사용되고 있는 C에 대한 폭넓은 지식을 다루고 있다. 단순히 C 언어의 문법과 사용법/예제를 나열하는 것이 아니라, C 언어가 동작하는 방식에 많은 부분을 할애하고, 객체지향, 유닉스 운영체제, 동시성, 프로세스간 통신까지 C 언어를 제대로 이해하고 원하는 대로 사용하기 위한 필수 지식들을 망라하고 있다.
이 책은 크게7개의 파트로 구성되어 있다. 1부에서는 전처리 및 지시자, 변수와 함수 포인터, 함수 호출 메커니즘 등 C언어의 필수 요소와 함께 소스 코드에서 이진 파일을 만드는 방법, 목적파일과 그 종류에 대해서 다루고 있다. 2부는 메모리에 대한 내용으로,프로세스 메모리의 레이아웃을 설명하며, 스택과 힙 세그먼트를 자세히 다룬다. 3부의 주제는 객체지향으로, 객체지향의 특징/속성 및 C 언어 및 C++ 언어로객체지향을 구현하는 방법을 소개한다. 4부는 유닉스의 역사와 아키텍처,시스템 호출과 커널에 대해 다루며 최신의 C 표준인 C18에대해 알아본다. 5부에서는 동시성의 개념을 살펴보고, 동시환경 및 인터리빙, 동기화, 스레드 실행, 스레드 동기화에 대해 다룬다. 프로세스 간 통신에 대해 다루는 6부에서는 프로세스 실행 방법, 동기화, 싱글 호스트 IPC와 소켓 프로그래밍을 소개하며, 마지막 7부에서는 테스트와 디버깅 방법, 빌드 시스템에 대해 설명하고 있다.
이 책은 C 언어를 사용하는 주니어 개발자 뿐만 아니라 개발 경력이 많은 시니어 개발자에게도 유용할 것으로 생각된다.
책 제목처럼 C에 대한 기본기를 다진 사람이 보기 좋은 책이다. 이왕이면, 필드에서 C를 사용하는 개발자나 흥미를 가져서 깊게 파고싶은 개발자, C++ 개발자가 아니면 권하고 싶지는 않다. 그래도 C에 대한 기본 문법과 중요한 것들을 첫 챕터부터 정리해주기는 한다. 하지만, 정리인 것이지 기초 문법을 다 알려주는건 아니므로 반드시 기본서를 1권 보기를 권장한다. C에 대한 독학을 위해 잘쓰여진 기본서들은 많으므로, 이를 꼭 보고 이 책을 보자.
3부인 챕터6의 OOP 파는 꽤 흥미로운 부분이다. 회사에서 개발을 하면서 좋은 객체지향 코드에 대해 고민하고 있는데, 그 원리는 C라고 해서 크게 다르지는 않는 것 같다. 표현하는 언어가 다른 것이지. 원리 등은 큰 줄기에서 관통하는 건 비슷하다는 느낌을 받았다. 챕터 하나하나가 깊이가 있기에, 본인의 내공을 깊게 하고 싶다면 이 책을 탐독하는 것도 큰 발전이 될 거라고 본다. 유니크한 개발자가 되고 싶은 개발자 모두에게 권장하고 싶다.
번역도 읽는데 크게 불편함은 없었다. 다만, 내용이 깊어서 읽으면서 생각을 여러 번 하게 되는 부분들이 뒤로 갈수록 나온다. 옆에 두고, 필요할 때마다 생각날때마다 보면 좋은 책임은 확실하다.
C언어는 자바, C++, C#에 비하면, 뭔가 올드하다는 느낌을 지울 수 없는 #프로그래밍 언어다. 실제 만들어 진지 오래 된 것도 있고, 최근의 프로그래밍 언어들이 도입한 많은 개념에서도 차이가 있다 보니, 개발자의 길에 들어서는 초보자들이 처음부터 선호하는 언어는 아니다.
그러나 개발 경험이 쌓이다 보면, C언어를 공부해야 할 필요성을 여기저기서 느끼게 된다. 특히 효율이 중요하거나, 프로그램 크기를 줄이고, 직접적으로 하드웨어를 제어할 필요가 있는 경우 더욱 그렇다. 유니티 같은 게임 엔진이 있지만, 게임에서도 C언어는 많은 위력을 보여준다. #유닉스, 리눅스 같은 운영체제에서 C언어는 말할 필요 없을 존재다. 뭔가 깊게 들어가려면, 어셈블리를 하든, C를 하든 둘 중 하나는 잘 알아야 한다. 게다가 C언어는 오래된 프로그래밍 언어인 만큼, 과거부터 지금까지 쌓아 놓고, 퍼져 있는 인프라가 무척 두텁고, 넓다. 그만큼 유지 보수 시장, 완전 갈아 엎는 재개발 시장도 많다.
그래도 C언어 인기는 확실히 높지 않다 보니, C언어를 주력으로 하는 개발자도 줄고, 책 또한 대부분이 입문 수준이라, 기초를 넘어 보다 높은 수준의 관련 기술을 습득하는데 어려움이 있다. 그런데 이번에 다행스럽게도 캄란 아미니의 책 '전문가를 위한 C'를 통해, 보다 진보한 #C언어 고급기술을 제대로 익힐 수 있는 가뭄에 단비 같은 기회를 얻을 수 있었다.
#전문가를위한C, 이 책에서는 일반적으로 알려진 C언어에서는 힘들다는 객체지향을 다루고 있고, 유닉스에서의 좀더 최신의 C를 다루는 방법, 스레드와 병렬처리를 위한 동시성, 멀티 프로세스와 동기화 같은 보다 깊은 프로세스 처리와 각종 소켓과 같은 통신 방법, C++, 자바, 파이썬, GO와 같은 다른 언어와의 통합 방법, 테스트와 빌드 시스템 설명을 포함한 테스트와 디버깅 기술에 대한 것들을 설명하고 있다. 대부분이 난이도가 있는 것들로 그나마 책 초반에 등장하는 파트1인 C프로젝트 빌드, 파트2인 메모리는 쉬운 주제에 속한다.
그만큼 '전문가를 위한 C'는 중급자 이상을 대상으로 하는 책이다. C언어를 배우는 데 있어, 포인터로 다들 한차례 난관을 치렀을 텐데, 이 책 수준은 이를 한참 넘는 입문자에게는 매우 어려운 내용임에 틀림없다. 더군다나 책 분량도 전체 912쪽이나 달한다. 그러나 다른 책에서는 볼 수 없는 내용들로 C언어 스킬을 높이는데 많은 도움을 주는 소중한 주제들이 담겨 있어, 결국에는 한 번쯤 보게 될 책이라 생각한다.
개인적으로 재미있게 본 주제는 객체지향 파트였다. 내 머릿속에 있는 C언어는 객체지향과는 거리가 먼 언어로, 그 때문에 C++이 등장했다고 알고 있었는데, C언어도 이미 #객체지향 개념을 가지고 있었다고 하니, 내 호기심을 유발하기에 충분했다. 이를 세 챕터에 걸쳐 설명하고 있는데, 역시 객체지향의 대표 언어인 C++과 비교하며 설명하고 있었다. 비교 덕분에 나름 이해하기 쉬웠고, C언어의 몰랐던 내재된 능력과 한계를 잘 알 수 있었다. 확실히 C언어에 대한 시야를 넓혀주는 파트였다.
그러나 C언어로 이렇게까지 객체지향을 구현할 필요가 있나 개인적으로 의문이 들었다. 객체지향 개념을 먼저 익힌 개발자나 코드에 객체지향이 필요한 상황에는 이 책의 내용이 아주 요긴하게 쓰일 것이다. 그렇지만, C는 C 다워야 하고, C++은 C++ 다워야 한다고 생각한다. 잘하는 걸 제대로 쓰는 게 더욱 중요하다고 생각한다.
내 경험상 가장 실용성이 높은 파트를 꼽는다면, 동시성과 프로세스 쪽이라 생각한다. C언어 뿐만 아니라, 모든 프로그램 언어 모두에게 중요한 파트다. 최근 인텔의 13세대 프로세서가 나와서 몇 코어니 하는데, 아무리 많은 코어를 가진 CPU가 나와도 이걸 제대로 사용하지 못하면, 아무 소용 없다. 요즘 전자제품에 쓰이는 칩들도 멀티로 가고 있는 만큼, 이는 꼭 필요한 고급 지식으로 이 책의 내용이 많은 도움을 준다.
책 내용 전체를 다 언급하지는 못했으나, '전문가를 위한 C'에서 다루는 7가지 파트 모두 개발자에게 많은 도움이 되는 유익한 것들이었다. 미처 몰랐던 C언어의 #고급기술 까지 알게 되어, C언어를 제대로 완전 정복했다는 뿌듯한 느낌마저 들게 한다. 프로그램 공부는 끝이 없지만...
한빛미디어에서 출간된 “전문가를 위한 C”라는 책은 현업에서 C / C++ 언어를 사용하는 사람들이라면 심도있는 주제를 다양하게 설명해놓았기 때문에 참고해보면 좋을 것 같은 책이다.
또한 최신 C언어에 대한 내용도 담고있고, 프로세스 간 통신 하는 내용과 다른 언어와 통합하는 방법, 테스트와 유지보수 등에 대한 세세히 담겨있어서 실무에 도움 될 수 있는 책이다. 주니어 및 시니어 둘 다 볼 수 있는 책이다. 마지막 장에서는 빌드 시스템에서 바젤 빌드와 CMAKE에 대해서도 다루고 있어서 꽤 쏠쏠했다.
책이 약간 두껍긴 하지만 그래도 실무에 도움 될 만한 내용들이 많기 때문에 C언어를 주로 사용하는 개발자라면 한 권쯤 가지고 있어도 좋을 듯 하다.
“한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다."
항상 프로그래밍 언어와 관련된 책을 리뷰할 때면 TIOBE Index를 인용해오곤 하는데, 현재 시점에서 C는 Python에 이어 2위에 위치해있다. C는 1972년 Dennis Ritchie가 만들었고, 올해는 언어가 태어난지 만 50년이 되는 시점이다. 물론 최근에는 뭔가 다방면으로 활용할 수 있는 언어들이 인기를 얻고 많이 사용되고 있지만, 그 중에서도 시스템 어플리케이션이나 low level programming에서는 여전히 C가 많이 사용되고 있다.
사실 이 이야기를 꺼낸 이유는 이 책을 단순히 C와 관련된 언어책이라고 처음 생각했기 때문에 그런것이다. 그래서 막연한 생각에 여타 시중에 나와있는 C 책들과 같이 C에 대한 문법, 알고리즘 구현, 조금 고급진 내용을 다룬다면 C로 만든 프로그래밍 구현 정도가 담긴 책이라고 생각했었다. 그런데 책에 담겨 있는 내용은 그렇지 않다.
이 책은 간단하게 말하자면 C 에 대해서 알수 있는 책이라기 보다는 C를 주로 활용하는 시스템 프로그래밍 책이라고 표현하는게 맞다. 그래서 책 서두부터 간단한 문법에 대한 내용이 아니라, C로 만든 프로젝트의 빌드방법부터 소개한다. 아마 다른 C로 구현된 오픈소스 코드를 보면 헤더나 소스에 막 복잡하게 정의되어 있는 전처리기 같은 것은 활용 방법과 빌드와 관련된 내용이 처음부터 소개되는 것이다. 이밖에도 C로 이뤄지는 Object Oriented Programming이나 Concurrency, IPC 같은 기초 책에서는 찾기 어려운 주제들로 내용이 구성되고 있다. 서두에서도 저자는 C를 활용한 다양한 프로젝트에서 겪은 극한의 주제에 대한 경험적 지식을 실용적으로 접근할 수 있다는 의미로 "Extreme C"라는 책이름을 지었다고 소개되어 있고, 사실 어떻게 보면 이책을 통해서 C로 할 수 있는 모든 내용이 거진 담겨져 있다. Unix를 다루는 부분에서는 조금더 실무적으로 시스템 프로그래밍을 어떻게 하는지에 대한 내용이 잘 담겨져 있다. 개인 여담을 좀 소개하자면, 이전에 블로그에 Xenomai 라고 하는 Custom kernel을 설치하는 방법에 대해서 소개했었는데, 그걸보고 연락주신 분이 안된다고 해서, 나도 처음부터 리눅스 커널을 빌드하고, 간단하게 모듈들을 수정하는 작업을 거쳤었다. 그런데 이게 참 C를 다룬지 오래되서 그런지 빌드부터 코드 수정이 익숙치가 않았다. 가령 어떤 부분이 잘못되었는지는 감이 오는데, 이 걸 수정하려니까 조금 막막했던 경험이 있었고, 사실 이 책을 통해서 조금이나 기름칠을 하려고 했었다. 물론 이 책을 통해서라면 조금 수월했을 일들이다. 이밖에도 후반부에는 다른 언어와의 통합성에 대한 내용도 다루고 있어서 C를 쓰는 사람들이 다른 프로그래밍 언어로 구현된 내용과 어떤식으로 통신을 할 수 있는지에 대한 내용도 소개되었다. 진짜 이런 내용은 어떻게 보면 stackoverflow나 이런데서 검색해야 찾을 수 있는 내용인데, 진짜 광범위한 내용을 다루고 있다는 느낌을 받았다.
다만 책의 분량 자체가 일반적인 책의 분량의 두배 수준이기 때문에(대략 900페이지?) 책의 전체 내용을 꼼꼼히 파악하는데까지는 시간이 많이 필요할 것으로 생각한다. 그리고 C로 다룰 수 있는 또다른 극한의 주제를 모두 다루기에는 이 책의 분량가지고도 부족할 것이다. 하지만, 적어도 주어진 분량내에서 이 책은 앞에서 언급한 고급 주제에 대한 내용과 예시들을 충분히 다루고 있으며, 이 내용만으로도 일일이 내가 경험했던 것처럼 stackoverflow를 찾아해메야 했던 사람들에게는 좋은 가이드를 제공하지 않을까 생각한다.
C는 오래된 프로그래밍 언어입니다. 다른 많은 프로그래밍 언어의 흥망성쇠에도 불구하고, 나온지 오래되었음에도 불구하고 중요한 프로그래밍 언어인것은 틀림없을것입니다.
한빛미디어에서 새로운 C 언어 책이 나왔습니다. 전문가를 위한 C 입니다.
C와 C++로 개발을 하는데 익숙하거나 그에대한 지식이 있는 독자들을 대상으로 합니다. 또한 메모리, CPU, 주변 장치들의 특성을 알거나 하면 책을 읽는데 도움이 됩니다. 여타 다른 한빛출판에서 나온 책들과 달리(초보자를 위한) 쉽게 다가가기 위한 그림 등은 배제되어있습니다.
책의 쪽 수도 900페이지가 넘어갑니다. 중급자를 넘어 전문가로 나아가는데 필요한 책인거같습니다.
C는 절차지향 프로그램이 언어이지만 챕터 3에는 객체지향 프로그래밍을 시도하는 부분도 있습니다.
책 대부분은자세한 설명, 고급활용, 그리고 운영체제등 광범위하게 다룹니다. 다른 프로그램이 언어를 사용할 때도 이 책에서 본 내용들은 많은 도움이 될 것입니다. C뿐만 아니라 C++를 사용하는 프로그래머라면 추천하는 책입니다..
달마다 그렇듯 한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받았습니다.
나는 처음 프로그래밍 언어를 C로 시작했다. 뭐 그 이전에 스크래치2 라는 '블록언어' 를 접해보긴 했었지만, 어쨌든 시작은 C였다.
그때 참고한 도서가 엄청 초보자용도 아니었고, 그렇다고 다른 언어 경험이 있는 사람들을 대상으로 한 것도 아니었지만 비교적 쉽게 문법을 이해해 나갈 수 있었고, 포인터는 크게 중요해 보이지 않아서(???) 그냥 이런게 있나보다 하고 그냥 넘어갔다.
그렇게 블록언어의 한계를 극복할 텍스트 언어를 접한 뒤, Python을 또 배우다 보니까 이거는 문법이 C 보다 더 간결해보여서 결국엔 Python을 주로 쓰게 되었다.
그리고 또 얼마 안있다가 아두이노를 접했는데. 아두이노가 C/C++ 기반 으로 프로그래밍해서 결국 한동안 잊어버린 C 를 복습해가며 Python 문법과 중첩되는 혼란을 겪기도 했다.
하지만 과연 내가 C 에 대해서 제대로 알았을까?
영어의 문법을 안다고 해서, 무조건 외국인과 자연스럽게 대화할 수 있는건 아니고, 심지어 글을 읽어도 의미를 이해할 수 없을 수도 있다.
그냥 프로그래밍 언어를 배우기 위해 C 를 선택했지만, 내가 컴공과 대학생도 아니었고 그래서 이거를 배워서 어디에 쓸지, 이 언어를 어떻게 하면 효율적으로 활용할 수 있는지도 몰랐다.
하지만 이제 프로그래밍 언어를 통해 개발을 하고, 프로그래밍을 공부할 때와는 달리 훨씬 제한된 시스템 환경에서 안정적으로 작동시키기 위한 최적화를 위해선 조금 더 깊이 파고들 필요가 있다.
아마 곧 프로그래밍은 단순히 독학에서 시작한 취미가 아니게 될 것이니 필수적이다.
일단 이 책은 C의 기본적인 문법을 독자들이 다 안다는 전제하에 시작된다.
그래서 처음에 매크로 부터 시작하는데, 나는 C에서 매크로라는 개념을 아예 처음 들어봤다.
여기서 내가 C를 지금까지 그냥 쓸 줄 아니까 쓴거지, 완전히 파악한 건 아니라는 것을 느꼈다.
이 책은 C 를 사용하는 다양한 시스템 구현에 관한 이론을 다루는데(아마 이것도 기본적인 축에 속하지 않을까), 서평 기간내에 다 읽지는 못할 것 같고, 비교적 빠른 시일 내에 내가 읽어봐야 할 챕터들을 정리해 보자면,
음- 아무래도 소켓 파트인 19, 20 빼고는 내년 초까지 틈틈히 읽어야 할 것 같다.
대다수 입문용 C언어 책들의 마무리인 포인터를 시작으로,
매크로, 컴파일, 어셈블리, 메모리, 힙/스택, 객체지향, 상속, 추상화, 유닉스, 병렬/동시성 프로그래밍, 스레드 및 프로세스에 관한것들, 다른 언어와 통합이나 유지보수 및 빌드 시스템에 관한 것 까지.
단순히 입문도서로 끝내지 말고 더 공부했어야 할 내용들이 가득하다.
책이 912 페이지로 상당히 두꺼운데, 책 표지가 한빛미디어의 다른 책들과 두께 차이가 거의 차이가 없다.
책이 더 쉽게 망가질 위험도 있고, 그런 면에서 하드커버로 출간되지 않은 것이 아쉽다.
아 그리고 전자책으로 받아볼 걸 그랬다. 많은 내용을 담으려면 물리적으로 부피가 커지는건 어쩔 수 없지만 무겁다.
마지막으로 C 뿐만 아니라 Python도 만만히 볼게 아니라 전문가를 위한 Python 같은 내용들이 있을 것 같은데, 찾아봐야겠다!
해당 책에서는 테스트한 환경(Ubuntu 18.04.6 LTS, gcc==7.5.0)을 잘 제시해주어 독자로 하여금 재현가능하게 잘 제시해주고 있으며, github(https://github.com/PacktPublishing/Extreme-C)도 잘 제시해주어 독자가 편리하게 테스트 할 수 있게 제공되고 있다.
무엇이 좋았는가?
책의 난이도는 중상급으로 분류되지만 해당 책은 다른 언어를 쓰다가 C를 접근하는 사람이 읽기에도 충분히 좋은 책일 것 같다는 생각이 들었다.
프로그래머가 작업을 못하게 방해하지 마라(Don't prevent the programmer from doing what needs to be done)
언어를 작고 간단하게 유지하라(Kepp the language samll and simple)
명령을 실행하는 방법을 하나만 제공하라(Provide only one way to do an operation)
호환성은 장담할 수 없더라도 빨리 작동하게 만들어라(Make it fast, even if it is not guaranteed to be portable)
첫 번째 프로그래머를 믿으라는 부분이 C언어의 핵심이라고 본다. 즉, 프로그래머가 C언어로 이것저것 할 수 있는 것은 언어 자체에서 프로그래머를 제한하지 않았기 때문이다. C언어가 탄생할 당시에는 이것이 당연한 게 아니였다고 한다. 제한하지 않았기 때문에 흑마법이라 불리우는 이상한 짓들이 가능했고, C언어가 전무후무하게 모든 기종에 포팅될 수 있었던 것이 딱 한 가지 역할만 했기 때문이다. CPU는 원시 자료형과 빠른 계산을 고수하는데 그렇게 설계되었기 때문이다. 이러한 점에서 C언어는 CPU 수준의 로직과 그리 멀지 않으며 쉽게 번역될 수 있는 타입 시스템을 가진다. 이것이 몇몇 회사나 조직에서 핵심 프레임워크를 아직도 C언어로 작성하고 유지하려는 이유이다. 즉, 이 언어는 원시적이라 오랜 기간 살아남을 수 있었던 것이다.
하드웨어를 직접 사용할 수 있는 게 C/C++ 언어의 핵심이다. 그렇기 떄문에 책에서도 메모리에 대해 2챕터에 걸쳐서 설명하고 있다. C언어 공식 홈페이지 문서를 보면 놀라울 정도로 양이 적다. 정말로 언어 자체는 최소한의 기능만 할테니 나머지는 프로그래머가 알아서 하라는게 느껴진다. C언어는 B언어의 어려움과 단점을 보완하려고 했으며 사실상 어셈블리어를 대신하는 시스템 개발 프로그래밍 언어가 되었다. 유닉스의 성공에 따라 수십만 명의 사람이 C언어를 사용할 수 있게 되었다. 책에서 10장부터 유닉스에 대해 등장하는데, C언어를 공부하다보면 자연스럽게 운영체제의 커널 단까지 알게 된다.
사실 C언어에 대해서만 본다면 이 책은 별로 권장하지 않는다. C언어에 대한 설명은 챕터 5장까지(약 250쪽, 책의 1/3)가 전부라고 볼 수 있다. 그 이후에는 C++도 언급하며 C와 어떤 차이가 있는지, C에서 어떻게하면 가능한지 등을 서술한다. 그 밖에도 C언어로 이런저런한 것이 가능하기 때문에 생기는 문법과 함수, 기능들을 설명한다. 대표적으로 상속과 다형성, 운영체제 커널과 동시성 프로그래밍, 프로세스 동기화, 소켓 프로그래밍이다. 마치 책은 C언어로 할 수 있는 모든 것을 총망라한 느낌이 든다.
'전문가를 위한 C' 책 타이틀 답게 이 책에서 가장 좋은 파트는 21장이라고 생각한다. 다른 언어와 통합하는 기능을 설명해주는데, C++을 가볍게 설명해주고, 자바와 파이썬, 심지어 Go언어에 사용할 수 있는 라이브러리를 만드는 방법을 설명해준다. 파이썬의 Numpy 라이브러리가 C언어로 구현된걸 생각하면 정말 좋은 챕터이다.
언어에서 프로그래머가 할 수 있는걸 제한하지 않았기 때문에 살아남았지만, 그만큼 배우기 어렵고 다루기 까다롭다.
단순히 언어 차원에서 제공해주는 라이브러리 뿐만 아니라 본인이 직접 필요한 기능들을 전부 구현할 줄 알아야 제대로 사용하는 언어이기 때문에 배우는 사람들이 줄어드는 추세다. 더군다나 최근 유튜브 댓글들은 보면 C언어는 구시대 언어며 사장될 언어이기 때문에 배울 필요가 전혀 없다는 사람들이 늘어나고 있다. 그러나 TIOBE 통계자료를 보더라도 여전히 많이 사용하는 언어이며, CPU 로직이 혁신적으로 바뀌지 않는 이상 C언어는 계속해서 살아남을 거라 생각한다.
원 제목은 Extreme C(극한 C)인데, 적절한 제목이라 생각한다. 말 그대로 C언어로 개발하는 사람들을 위한 전문가를 위한 책이다. 기본 서적으로는 적합하지 않지만, 시스템 호출과 임베디드 환경 등 C언어로 개발, 유지보수 하는 전문가들에게는 한권쯤 옆에 끼고 볼만한 책이라 보여진다.
처음 책을 고를때 매우 망설였다. 왜냐면... 무려 912페이지나 되는 한손으로 들기에도 버거울?만큼 매우 무거운 책이었기 때문이다. 하지만, C++을 배우고 있으면서 C도 공부해봐야겠다는 생각을 예전부터 가지고 있었기 때문에, 한번에 다 볼 생각은 아니고, 사전 혹은 언제든 꺼내볼 수 있는 전공책처럼 곁에 두고두고 살펴보기 위해 이 책을 선택하였다.
예상?했던 것처럼 쉬워보이는 내용은 아니었다. 목차에서부터 생소한 내용들이 많이 있었고, 앞부분 프로그래밍의 기초적인 부분 외에는 Part3 객체지향 부분이 반가웠던 것 외에는 낯설었다.
저자가 설명하는 예상 독자는 다음과 같다.
- C와 C++ 개발에 관해 최소한의 지식을 가진 독자
- C/C++ 주니어와 중급 엔지니어가 주요 독자
- 책을 읽고 나서 시니어 엔지니어로 거듭날 수 있기를 원하는 사람
- 더 높은 연봉과 훨씬 더 유의미한 직무를 맡을 수 있기를 바라는 사람
- 시니어 엔지니어도 일부 세부 사항이 도움이 될 수도...
하지만 옮긴이는 초보자가 시니어가 될 때까지 옆에 두고 계속 보아도 좋은 책이라고 설명해주셨다,
나는 다른부분들 보다는 요즘 공부하고 있는 객체지향에 대해서 관심이 있어 Part3 부터 조금씩 살펴보았다. 사실 다른 설명들보다도, 객체지향을 우리 인간의 사고와 비교하며 설명해준 부분이 제일 인상깊어 그 부분을 일부 공유하고자 한다.
(pg 253) ~객체지향을 지원하지 않는 언어로 객체지향 프로그램을 작성할 수 있을까요? 정확히 말하자면 C 언어를 사용해서 객체지향 프로그램을 작성할 수 있을까요? ... 네, 가능합니다. ... OOP가 실제로 무엇을 의미하는지 살펴봐야 합니다.
(pg 253) OpenSSL과 OpenCV와 같은 여러 C 라이브러리는 모두 객체지향 방식으로 작성되었습니다. 이것이 C가 객체지향이라는 의미는 아닙니다. 그보다는 이러한 프로젝트가 내부 구조를 구성하는 방식이 객체지향적 사고방식에서 비롯한다는 뜻입니다.
(pg 254) C는 문법상 객체지향을 특징으로 삼을 수도 없고 그래서도 안 됩니다. ... C로 객체지향 프로그램을 작성할 수는 있지만, 복잡성을 해결하려면 추가로 약간의 수고가 듭니다.
(pg 254) ~ OOP는 문제를 생각하고 분석하는 방식에 더 가깝습니다. OOP는 전 우주와 그 안에 있는 대상(object)의 위계질서에 관한 태도입니다. OOP는 기본적으로 우리 주변의 물리적 개체(entity)와 추상적 개체를 이해하는, 오래전부터 전해 내려온 고유한 방법입니다. 이는 자연을 이해하는 매우 기본적인 방식입니다.
(pg254) 우리는 언제나 모든 문제를 객체지향적 관점에서 생각했습니다. OOP는 인간이 항상 채택했던 것과 같은 관점을 적용하는 것에 불과합니다. 다만 이번에는 계산 문제를 해결하기 위해 프로그래밍 언어를 사용할 뿐입니다.
(pg 257) 개념이란 사고(thought) 또는 생각(idea)으로, 마음속에 존재하는 정신적 또는 추상적 이미지입니다. 개념(concept)은 현실 세계의 개체(entity)에 관한 인식으로 형성되거나, 단순하게는 완전히 가상적(imaginary)이며 추상적(abstract)일 수 있습니다. 나무를 보거나 자동차를 생각할 때 이에 해당하는 이미지가 서로 다른 두 가지 개념으로 떠오릅니다.
(pg 258) 무언가를 설명하려는 목적은 관련한 구체적인 개념을 청중에게 전달하는 것입니다. ... 누군가가 마음속 지도를 가졌으며, 그 지도에는 다양한 개념과 그 개념이 서로 연결되는 방식이 나타납니다. 목표는 이 마인드맵을 청중에게 전달하는 것입니다.
(pg 259) 여러분은 문제의 개념 및 개념 사이에서 발견한 관계에 기반한 접근 방식을 사용해서 문제를 해결합니다... 컴퓨터를 이용해서 문제를 해결하려고 할 때 바로 이런 일이 일어납니다. 문제를 객체와 그들 간의 관계로 나눈 뒤, 이 객체를 기반으로 궁극적으로 문제를 해결하는 프로그램을 작성하려고 합니다. 여러분이 작성하는 프로그램은 마음속 개념과 그 관계를 모방합니다(simulate).
(pg 260) 객체지향 프로그램은 객체의 측면에서 개념을 모방합니다. 우리가 마음속으로 문제에 관한 마인드맵을 생성하는 동안, 프로그램은 메모리애 객체 모델을 생성합니다. 다시 말해 인간과 객체지향 프로그램을 비교하면 개념, 마음, 마인드맵과 같은 용어는 객체, 메모리, 객체 모델에 각각 대응합니다.
(pg 260) (컴퓨터를 사용하는 이유를 설명하며...) 마인드맵은 감정에 따라 잊히거나 변경될 수 있습니다. 하지만 컴퓨터는 감정이 없고 객체 모델은 인간의 생각보다 훨씬 튼튼합니다. 이러한 이유로 객체지향 프로그램을 작성해야 합니다. 마음속 개념을 효율적인 프로그램과 소프트웨어로 전달하기 위해서입니다.
객체지향에 대해 우리가 마음속으로 문제를 대하는 방식과 비교하여 설명해준 부분이 지금까지 이 책을 읽은 부분중에서는 가장 백미인 것 같다.(적어도 나에게는...) 아직 읽지 못한부분이 더 많기는 하지만 거의 매일 조금씩 천천히 살펴보면서 배워가고 있다. 저자가 설명한 것처럼... 시니어가 되기 위한 길에 도움을 주는 든든한 구글과 같은 책일 것 같다는 생각에 꾸준히 학습해볼 예정이다.
초반 개발을 시작할때는 대부분 C 언어를 사용하곤 했다. 처음 개발을 시작한 환경탓도 있겠지만 어느 정도 개발업무를 한다는 사람은 대부분 C 언어에 대한 지식을 기본으로 가지고 있었던 것 같다. 그만큼 개발 언어에 대한 서적도 C 언어에 대한 문법이나 고급 스킬을 소개하는 서적이 많았던 것으로 기억한다. 하지만 시간이 흐름에 따라 C 언어보다는 Java나 python 등과 같은 언어가 대세를 이루고 있는 것 같다.
이런 분위기에서 <전문가를 위한 C>는 오랜만에 보는 깊이있는 C 언어 서적이라고 생각한다. 이미 기초 문법은 알고 있다고 가정하고 개발 환경 및 다양한 개념에 대해 소개하고 있다. 특히 C 언어에서 필수적으로 알아야 하는 메모리 구조 및 스택, 힙에 대한 개념을 상세히 설명하고 있기 떄문에 어느정도 기초를 알고 있는 개발자에게는 개념을 잡는데 많은 도움이 되지 않을까 생각이 들었다. 이뿐만 아니라 C 언어의 기반이 된 유닉스의 역사 및 아키텍처, 시스템 호출과 커널 등에 대한 소개를 통해 C 언어가 탄생하게 된 배경과 low level 언어로서의 C 언어를 이해할 수 있다.
C 언어는 오랜 역사를 가진만큼 다양한 분야에서 많이 사용되고 있다. 특히 임베디스 시스템이나 고성능 시스템 개발에 최적화된 언어라고 볼 수 있으며 시스템의 하드웨어를 어느정도 직접 컨트롤할 수 있다는 면에서 소프트웨어 엔지니어링 등에서 핵심 언어로 자리매김하고 있다. 요즘 세부 하드웨적인 지식이 없더라도 개발할 수 있는 언어가 다양하게 나와있다. 하지만 하드웨어적인 시스템을 알고 개발하는 것과 아닌 것과의 차이는 상당히 크다고 볼 수 있다. 그런 측면에서 C 언어로 개발을 할 수 있는 개발자가 다른 언어를 사용해서 개발하는 것과 전혀 모르고 개발하는 사람과의 차이도 그만큼 크다고 볼 수 있을 것 같다.
이 책은 C 언어와 컴퓨터의 역사, 객체지향(이 부분이 추가된 것에 대해서는 좀 의문이다), 커널, 프로세스 등 다양한 주제를 가지고 설명한다. 그리고 각 설명마다 다양한 예시가 제시되어 있어서 실제 각자의 환경에서 컴파일하고 실행해 볼 수 있기 때문에 직접 눈으로 보고 그 결과를 확인할 수 있다. 하지만 프로그래밍 언어를 전혀 모르는 사람이 이 책을 통해 C 언어를 배우기는 쉽지 않을 것이다. 이 책의 서두에도 언급하듯이 이 책을 읽기 위한 최소한의 요구사항을 제시한다: 컴퓨터 아키텍처 지식, 프로그래밍 기초 지식, 터미널과 쉘 명령어 사용법, 프로그래밍 중급 지식, 객체 지향 프로그래밍 기초 지식이 그것이다. 적어도 최소한의 요구사항에 대한 용어를 들어보거나 경험한 적이 있어야 이 책이 설명하는 내용을 제대로 따라갈 수 있으리라 생각한다.
편의성 측면을 본다면 개발자가 리소스와 프로세스 스케줄링에 크게 신경쓰지 않고 원하는 기능을 개발할 수 있으면 좋을 것이다. 하지만 그렇게 되기 위해서는 또 다른 개발자가 리소스와 프로세스 스케줄링을 자동으로 잘 제공할 수 있는 기능이 개발되어야 할 것이다. 누군가가 편하게 사용하기 위해서는 누군가는 그 기반이 되는 구조와 환경을 제대로 구현하고 있어야 한다(예를 들어 개발자가 시스템적인 고민을 별로 안해도 되는 python의 경우 내부는 C로 구현되어 있다).
C 언어가 가지고 있는 장점은 다른 언어에 비해서 월등한 것 같다. 그만큼 개발자가 신경써야 하는 것이 많긴 하지만 그만큼 원하는 방향대로 디테일하게 제어할 수 있다는 것이기도 한다. 이 책은 이런 개발자를 위해 C 언어에 대한 깊이있는 지식을 전달해 준다. 개념을 배우고 실제 컴파일해서 경험하는 과정을 통해 그 지식을 한층 높일 수 있다고 생각한다. 그리고 한층 높은 단계로 올라갈 수 있는 사다리가 되지 않을까 생각한다.
C 언어는 시스템 자원을 관리하는 운영체제 개발을 위해 만들어진 언어이다. 따라서 하드웨어를 제어하고 실행 효율을 높여야 하는 곳에 주로 쓰인다. 우리 주위에서 흔히 볼 수 있는 신호등, 자동차의 중앙 컴퓨터(CPU), 주방의 전자레인지, 스마트폰의 운영체제 등 별생각 없이 봤던 다른 장치 모두 C로 작성된 소프트웨어를 사용한다.
C는 죽은 언어라는 오해와 일부 기술 전문가들의 무시에도 불구하고, 티오베에서 확인할 수 있는 티오베 지수는 이를 반증한다. C는 자바와 함께 지난 15년간 가장 인기 있는 언어였다. 그리고 최근 몇 년 동안 인기가 더 높아지고 있다.
전문가를 위한 C
이 책은 C 언어라는 만만치 않은 주제에 Extream C 라는 원서의 제목에 맞게 C 언어의 모든 부분을 다룬다.
따라서 대상 독자 또한 C와 C++에 관해 최소한의 지식을 가진 독자를 대상으로 한다.
이 책을 시작하기 전에 잘 알고 있어야 할 주제들은 다음과 같다.
컴퓨터 아키텍처 지식
프로그래밍 기초 지식
터미널과 셸 명령어 사용법
프로그래밍 중급 지식
객체지향 프로그래밍 기초 지식
책은 총 7부 23개의 챕터로 구성된다. 각 부에서는 C 프로그래밍의 특정 측면을 다룬다.
1부는 C 프로그램을 작성할 때 매우 유용한 C의 특정 요소를 주로 다룬다. 구성 요소에는 전처리기 지시자, 포인터 변수, 함수 포인터, 구조체 등이 있다.
2부에서는 프로세스 내부의 메모리 및 메모리 구조를 다룬다.
3부에서는 C언어의 객체지향을 다룬다. 객체지향과 C가 무관한 듯 보일 수 있지만, C에서도 객체지향적인 코드를 작성할 수 있다. 객체지향 방식에서 문제를 설계하고 해결하는 알맞은 방식 및 가이드를 소개한다.
4부에서는 유닉스와 C의 관계, 5부에서는 동시성을, 6부에서는 프로세스 간 통신을 다루며, 마지막으로 7부에서는 테스트 및 유지 보수에 관해 다룬다.
결론
이 책은 C를 이용하는 애플리케이션의 개발과 유지 보수에 필요한 기초와 고급 지식을 모두 다룬다.
일반적으로 프로그래밍 언어의 문법만 안다고 해서 성공적인 프로그램을 작성하기란 어렵다. C는 다른 언어에 비해 이 점이 더 중요하다. 이 책에서는 대규모 소프트웨어를 C로 작성하는 데 필요한 모든 개념을 살펴본다. 간단한 단일 프로세스 프로그램부터 복잡한 멀티 프로세스 시스템에 이르기까지 말이다.
또한 C 언어 그 자체뿐만 아니라 C 언어와 컴퓨터의 역사, 객체지향, 커널, 스레드, 프로레스, 다른 언어와의 통합에 이르기까지 그야말로 여러 주제를 폭넓게 다룬다. 그만큼 C언어가 IT 기술에 미치는 영향이 방대하다는 증거이다.
필자도 현재 '전문가를 위한 파이썬'이라는 책을 보는 중인데, 책의 내용은 초보자가 보기에 당장에 이해하기도 어렵지만 실제로 적용해볼만한 코드를 작성하기도 쉽지 않다. 이 책도 마찬가지이다. C 언어를 꾸준히 사용한 지 최소한 1 ~ 2년 정도 지난 엔지니어들이 자신들이 계속 고민해왔던 부분들에 대해 생각해보면서 기반이 되는 지식과 더불어 이 책을 최대한 활용할 수 있을 것 같다.
이 책은 임베디드 및 커널 전문개발자인 캄란 아미니 저자가 쓰고 판교의 프런트엔드개발자인 박지윤역자가 번역한 책이다. 우주의 초기발생에 관심있는 임베디드 개발자가 쓴 책이라 그런지 스택을 직접 구현하는 등 매우 저수준내용부터 C++과의 테스트 등 고수준 내용까지 방대하게 다루고 있다. 이 책을 보면 C 언어도 C11을 시작으로 모던(modern) C로 변화가 이루어지고 있다는 사실을 확인할 수 있다. 이 책을 읽으며 인상적이었던 부분은 C11 이후의 변화뿐만 아니라 C 언어의 특성과 활용을 좀 더 깊이 있게 다룬다는 점이다. 예를 들면 C 언어를 C++과 비슷하게 사용하려면 어떻게 표현할 수 있는지, 소스 코드가 최종적으로 플랫폼에서 실행되기까지의 과정을 상세하게 설명한다. C 언어는 다른 언어와 통합하기 쉬운 언어인데 이와 관련된 내용도 다루며 C 언어로 작성한 라이브러리를 다른 언어와 연동해보는 연습도 매우 유용한 내용이다. 모던 C뿐만 아니라 C 언어가 실행 파일로 변환되는 과정과 C++ 언어와의 비교하여 테스트 더블을 해 보는 방법 등은 상당히 흥미로웠다.
이 책의 장점은 각각의 OS와 각각의 컴파일러에 대해서도 실행하는 방법을 알려주고 있고, 네트워크도 전화통신망(PSTN)부터 socket까지 매우 저수준의 내용을 잘 다루고 있다는 점이다.
이 책의 단점은 설명하는 문장들이 초보자가 보기에는 너무 어려운 상태라는 것이다. 예를 들면 "이 정의는 모든 스택 객체가 배열로 저장되며, 무엇보다도 스택에 어떠한 값이라도 저장할 수 있다는 의미입니다." 같은 내용이다. 그리고 역자가 영어에 능통한 사람이라서 원문 자체를 그대로 영어스럽게 번역을 한 부분도 살짝 이해하기 어렵다. 예를 들면 "macOS에서는 gcc가 알려진 명령어이고 clang컴파일러를 가리킬 때, 정확히 이와 같은 명령어를 실행할 수 있습니다." 같은 문장이다. 그냥 한국어로 "만약, clang컴파일러를 사용하시려면 셀 박스 21-3의 내용을 입력하세요." 정도가 간결하다. 추가로 욕심을 내자면 gui 연동도 함께 있었으면 싶었다.
하지만 역시 "전문가를 위한" 시리즈 답게 광범위한 내용을 다루는 점에서 많은 사람들에게 추천하고 싶다.