C++

C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.

— 비야네 스트롭스트룹 박사가 위트 있게 던진 C++의 압도적인 파괴력과 복잡성에 대한 전설적인 경고

성능 향상을 위해서라면 복잡성과 문법적 기괴함 따위는 가볍게 눈감아 주는 극단적인 제로 오버헤드 원칙의 화신이자, 오늘날 전 세계 수억 명이 매일 쓰는 크롬 웹 브라우저 엔진의 밑바닥을 악착같이 지탱하고 있는 수호성인. 분명 언어 사양은 발전했다고 하는데, 최신 표준을 보면 이게 자바스크립트인지 쉘 스크립트인지 외계인의 소스코드인지 분간이 가질 않는 기괴한 기호들의 향연을 감상할 수 있다.(...)

1. 개요

1979년 덴마크 출신의 컴퓨터 과학자 비야네 스트롭스트룹 박사가 벨 연구소에서 'C with Classes'라는 프로젝트명으로 시작한 역사적인 프로그래밍 언어. C언어의 강력한 시스템 제어 능력을 고스란히 보존하면서, 클래스를 주축으로 하는 객체 지향 프로그래밍(OOP), 일반화 프로그래밍(Generic Programming), 함수형 기능 등 온갖 강력한 프로그래밍 아키텍처를 누더기처럼 기우며 다중 패러다임 언어의 최강자로 거듭났다. Unreal Engine 등 초고화질 3D 그래픽 게임 엔진, 텐서플로우 등 딥러닝 연산 백엔드, 금융권 초고속 매매 알고리즘 등 단 0.0001초의 딜레이도 용납하지 않는 분야에서 단연 독보적인 제왕으로 군림하고 있다.

2. 타협하지 않는 가치: 제로 오버헤드 원칙

C++을 관통하는 가장 위대한 설계 사상은 '사용하지 않는 것에 대해서는 비용을 지불하지 않는다'제로 오버헤드(Zero-overhead Principle) 원칙이다. 이는 추상화 레이어를 씌워서 프로그래밍을 더 편하게 만들더라도, 그것이 최종 실행 속도에 어떠한 악영향도 미치지 않고 순수 C언어로 하드코딩한 수준의 극대화된 속도를 보장해야 함을 뜻한다. 이를 위해 컴파일 시점에 클래스나 템플릿의 타입을 완벽히 분석해 메모리 구조를 사전에 완전히 정해두는 강력한 정적 타입 시스템다형성 정적 바인딩을 사용한다.1 또한, 메모리를 객체의 수명과 일치시키는 RAII(Resource Acquisition Is Initialization) 기법과 스마트 포인터(Smart Pointer)의 도입으로 모던 C++에 이르러서는 수동으로 free를 호출하는 원초적인 노가다를 상당 부분 제거하는 우아한 발전도 거두었다.

3. 방대함이 낳은 기괴함과 템플릿 메타프로그래밍

C++의 최대 강점이자 숨 막히는 약점은 역설적이게도 압도적으로 방대하고 복잡한 기능들이다. 하위 호환성을 목숨보다 소중히 여겨 초기 C언어 코드까지 고스란히 지원하는 탓에 버려지는 스펙이 단 하나도 없다. 다중 상속으로 인한 '죽음의 다이아몬드(Diamond of Death)' 상속 계층 문제, 가상 함수 테이블(vtable) 호출의 미세 오버헤드를 막기 위해 도입된 극단적인 템플릿 메타프로그래밍(Template Metaprogramming) 등은 언어 학습 난이도를 안드로메다로 날려 보낸다.실제로 구글이나 메타 같은 테크 기업들조차 자사 규정집에 C++의 특정 기형적 기능은 사용을 엄금하는 금지 조항을 대거 명시해 둔 상태다.2 이 복잡함을 해결하겠다며 최근 Rust가 메모리 안전성을 완벽히 담보하며 도전장을 내밀고 있으나, 지난 수십 년 동안 C++로 단단하게 빌드업된 전 세계 메가 엔터프라이즈 레거시 시스템들의 견고한 성벽을 무너뜨리기엔 아직 역부족이라는 평가가 지배적이다.

4. 템플릿 컴파일 에러의 공포

4.1. 수만 줄짜리 외계어 컴파일 에러 메시지

C++ 개발 도중 'std::vector'나 'std::map' 같은 표준 템플릿 라이브러리(STL)를 사용하다가 사소한 오타나 타입 불일치 오류를 범했을 때 터지는 대참사 드립이다. 비주얼 스튜디오(Visual Studio)나 gcc 컴파일러가 '단 한 줄'의 소스코드 오류에 대해, 수백 킬로바이트(KB) 용량에 달하는 방대한 중첩 템플릿 컴파일 실패 내역을 빨간색 콘솔 폭탄으로 투하해 개발자의 혼을 빼앗는다. 메세지 중간중간 섞여 있는 뾰족 괄호('< >')와 외계어 같은 주소들을 해독하다 지쳐 모니터를 끄고 퇴근하는 개발자들의 심경을 대변하는 역사적 밈으로, 모던 C++20 표준에 이르러서야 겨우 '콘셉트(Concepts)'라는 제약조건 도입을 통해 이 에러 로그를 조금이나마 인간적인 수준으로 다듬을 수 있게 되었다.(...)

5. 여담

  • 이름에 얽힌 소소한 위트: C++이라는 작명은 C언어의 증가 연산자인 ++(1을 증가시키는 코드)에서 유래했다. 즉, 'C언어에서 한 단계 더 진화한 다음 세대'라는 기발하고 전산학적인 위트가 듬뿍 담긴 이름이다.
  • 창시자조차 고개를 가로젓는 언어: 비야네 스트롭스트룹 박사는 인터뷰에서 '지구상에 C++의 모든 디테일과 기능들을 100% 완벽하게 이해하고 사용하는 인간은 존재하지 않는다. 나조차도 종종 표준 위원회가 새로 추가한 스펙들의 상호작용 결과를 예측하지 못해 레퍼런스를 뒤적거린다'고 털어놓으며 언어의 우주급 난이도를 직접 인증했다.
  • 크롬 브라우저의 구세주: 우리가 매일 쓰는 크롬 웹 브라우저의 렌더링 엔진인 블링크(Blink)와 자바스크립트 엔진인 V8은 모두 C++로 개발되었다. 극도의 속도로 자바스크립트 스크립트를 파싱하고, 초당 60프레임이 넘는 웹 그래픽을 매끄럽게 그려낼 수 있는 힘은 오직 C++의 고도화된 메모리 제어 아키텍처 덕분에 가능한 것이다.

6. 관련 문서

각주

  1. 컴파일 시간 다형성을 보장하는 템플릿 기법은 가상 함수 테이블 참조를 통한 런타임 간접 호출 오버헤드를 제로(0)로 압축함으로써 하드웨어 레벨의 절대적 퍼포먼스를 완성해 낸다.

  2. 실제로 C++ 프로젝트의 컴파일 타임은 온갖 헤더 파일 참조와 템플릿 코드 풀기 작업 때문에 타 언어에 비해 괴물 수준으로 길어지기로 악명이 자자하다. 빌드가 시작되면 메이저 커피숍에 다녀와도 빌드가 돌고 있는 광경을 볼 수 있다.