C++11 이후 달라진 현대 C++의 기능, 생태계, 창작의 자유, 그리고 단점까지—왜 지금 C++이 다시 ‘재밌는’ 언어인지에 대한 솔직한 고백.
글쓴이 Zed A. Shaw 스스로에게 솔직하게 물어보자. 프로그래밍을 하면서 진짜 _재미_를 느낀 게 마지막이 언제였나? 돌아보면 나는 거의... 10년 가까이 프로그래밍을 하면서 재미를 못 느꼈던 것 같다. JavaScript, Python, Ruby, C, 아무것도 재미없었다. 내가 말하는 "재미"는, 프로젝트를 하며 진심으로 설레고, 하는 내내 "젠장 이거 쩐다. 내가 떠올린 그 미친 아이디어가 진짜 먹히다니!"라고 생각하는 그 감정이다.
예를 들어, 나는 작은 로그라이크 게임을 만들고 있는데 문득 이런 생각이 들었다. "맵을 뒤집어서 다익스트라 알고리즘을 돌리면 맵 생성 중에 방들을 연결할 수 있지 않을까? 그러면 방 사이에 멋지게 깎인 터널이 생기겠지." 그러고 나서 그걸 구현하는 내내 정말 즐거웠고, C++이 방해된다는 느낌도 없었다. 결국 성공했고 그 과정에서 많은 걸 배웠다. 그러다 또 "내 FTXUI 사용자 인터페이스를 그냥 SFML 렌더 윈도우에 직접 렌더링할 수 있을까?" 하고 생각했다. 역시나, 그것도 아주 잘 됐다. 어렵지도 않았고, C++이 유니코드를 어떻게 다루는지도 많이 배웠다. 이게 쉽진 않았지만, 전부 가능했고 C++이 내 하고 싶은 일을 막는 경우는 거의 떠오르지 않는다. 그게 바로 재미다.
나는 프로그래머들이 처음 프로그래밍을 시작했던 이유를 잃어버렸다고 생각한다. 나는 코드를 배운 게 몇몇 억만장자들의 재산을 더 불리려고 배운 게 아니다. 불변 렌더링 엔진과 씨름하다가 콘플라워 블루 버튼 하나 띄우려던 것도 아니다. 랜덤한 오픈소스 프로젝트 꼭대기에 있는 몇몇 권위주의자들을 기쁘게 하려고 프로그래밍을 시작한 건 더더욱 아니다.
나는 프로그래밍이 재미있어서 시작했다. 새벽 4시까지 버티며 형편없는 gwBASIC 코드로 MS-DOS 콘솔에 글자 하나 찍어보려고 발버둥치던 기억이 있다. 그냥 아이디어가 있어서 몇 주씩 이상한 GUI 아이디어와 네트워크 서버를 붙잡고 씨름했다. 한 달 내내 싸우던 버그가 사실 멍청한 오탈자였다는 걸 알게 됐던 그 기억도 있다. 나는 기억한다. 좌절감마저도 엄청나게 재미있었다는 걸. 내가 배운 어떤 것보다도 훨씬 재미있었다.
그리고 확실히 기억나는 게 하나 더 있다. C++도 재미있었다는 거다. 그것이 과대평가되고 솔직히 형편없던 언어였던 시절에도 말이다. C++로는 웬만한 건 뭐든 만들 수 있었기에 재미있었다. Python 일루미나티가 C++ 프로젝트 코드에 형편없는 래퍼를 하나 만들어줄 때까지 기다릴 필요가 없었다.
하지만... 어딘가에서 C++은... 재미없어졌다. 그리고 그 흐름은 오늘날의 모든 언어들에도 이어진 것 같다. C++의 이야기는 다른 언어들에게 줄 수 있는 경고이자, 아무도 눈치채지 못한 위대한 부활의 스토리다.
90년대 후반에서 2000년대 초반, 나는 C++과 Java를 둘 다 활발히 쓰다가, C++ 커뮤니티가 아래와 같은 짓을 하기 시작하던 바로 그때쯤 C++를 거의 그만뒀다:

그때의 느낌이 딱 이랬다. 멍청이들이 새로 발견한 꺾쇠 괄호 모양의 템플릿 메타프로그래밍 망치를 들고 반경 100미터 안의 못처럼 생긴 모든 것을 사정없이 후려치는 꼴. 템플릿으로 두 수를 더하는 게 두 수를 그냥 더하는 것보다 "빠르다"고 우기던 사람들과 미친 토론을 하던 기억이 있다. 어셈블리 출력이 똑같은데도 말이다.
이렇게 모든 것에 템플릿 메타프로그래밍을 쓰려는 집착—그리고 프로그래머에게 친절하게 만들려 하지 않던 C++ 표준위원회의 괴상한 오만함—이 나와 많은 사람들에게 C++을 망쳐놓았다. 실제로 쓰기 좋은 언어를 만드는 것보다 Pimpl 패턴과 메타프로그래밍을 더 사랑하는 아키텍처 우주비행사들을 위한 언어가 되어버렸다.
그래서 내가 Java를 사랑했다. Sun Microsystems는 프로그래머와 그들의 필요를 진짜로 신경 썼다. Java에는 가비지 컬렉터가 있었다! Java는 절대 똑같은 길을 걷지 않을 것 같았다. 전혀 아니다. Java 프로그래머들이 말도 안 되는 보일러플레이트, AbstractFactoryFactory Visitor 패턴, 사용성보다 표준을 더 중시하는 것에 집착하게 될 리가? 아니, 절대. <기침>
아마 이때가 내 또래의 많은 사람들이 C++을 떠나던 시기일 것이다. 여러분 대부분도 꺾쇠 괄호 <>만 잔뜩 달린 장황하고 복잡한 문법에 비해 그다지 얻는 게 없는 언어로 기억하고 있을 것이다.
하지만 C++은 계속 진화했다. 그리고 표준위원회도 뭔가 하지 않으면 10조 달러짜리 단 하나의 산업에서만 쓰이는 비참한 마이너 언어가 될 거라는 사실을 깨달은 것 같다. 얼마나 한심한가!
그들은 일을 해냈고, 언어를 극적으로 개선했고, 원래의 목표도 잃지 않은 채 다시 재미있게 만들었다. 안타깝게도 이 거대한 C++ 혁신을 아는 사람이 거의 없어서, 내가 여러분의 인식을 업데이트해보려 한다.
C++11에서 C++에 추가된 것들을 한번 보자. 어서, 링크를 눌러 그 미친 듯한 개선 목록을 보라. 몇 가지 거대한 변화를 강조하자면:
auto — 그래, C++에 자동 타입 추론 키워드가 실제로 추가됐다. 나도 너만큼 놀랐다. 같은 단어를 이유도 없이 계속 치게 만들던 재수 없는 깐깐쟁이 언어가 C++인 줄 알았으니까.nullptr — 뭐라고? 그래, NULL이라는, 0이면서 0이 아닌 이상한 C의 헛소리를 고쳤다. 아직도 13.5비트 워드에 0 주소가 없는 PDP-11로 코딩하는 C 표준위원회 어느 등신 때문이지.range-for — 이거 제대로 읽은 거 맞다. 그래, C++에는 Python의 for(x in list)와 비슷한 이터레이터와 문법이 있다. 게다가 auto와 함께 작동한다. 그래서 리스트를 돌면서 타입을 맞출 걱정을 안 해도 된다. JavaScript는 아직도 for-loop가 뭔지 못 정했지만 C++은 갖췄다.lambda expressions — 뭐라고?! 그래, C++에 람다가 있다. 그리고 Python의 람다 같은 헛소리가 아니다. C++의 람다는 너무 좋아서 설계 접근 자체를 크게 바꿔버린다. FTXUI가 람다를 어떻게 쓰는지 보면 API 사용성이 얼마나 좋아지는지 알 수 있다.<chrono> — 방금 무슨 일이 일어난 줄 아는가? 2011년에 C++은 내가 써본 거의 모든 언어보다 더 나은 기본 시간 라이브러리를 가졌다. 100ms라고 쓰면 100밀리초 시점을 만들 수 있다. 그래, 이게 유효한 문법이고 타입도 안전하다.<regex> — 뭐라고? 그래, C++에는 빌트인 정규식이 있고 꽤 괜찮다. "ECMAScript" 모드에서 JavaScript와 완전히 똑같지는 않다는 단점이 있지만, 그 외에는 정말 잘 작동한다.unique_ptr와 shared_ptr — 그래, 다양한 형태의 참조 카운팅과 메모리 소유권 강제를 구현한다. 이게 들어오면서 사람들은 대체로 무분별한 힙 할당을 줄이고, 스택을 더 많이 쓰면서 필요한 곳에만 이 포인터들을 쓰는 쪽으로 바뀌었다.<thread> — 그래! 멀티스레딩이 언어에 기본 내장됐다. 이게 무슨 언어지? 내가 기억하는 C++은 "스레드가 필요해? 그럼 직접 짜, 멍청아."였는데, 새로운 C++은 "그래! 스레드는 정말 좋지! 여기 있어."라고 말한다.정확히 무슨 일이 있었던 건지, 왜 C++11이 이렇게 엄청난 개선이었는지 모르겠지만, JavaScript 세계의 ES6을 떠올리게 한다. 이전 방식과의 단절 없이도 언어의 철학과 스타일을 완전히 갈아엎은 업그레이드였다.
더 중요한 건, 이제 C++은 다른 언어에서 기대하는 것들을 꽤 많이 갖춘 더 현대적인 언어가 되었다는 점이다. 흔히 필요할 수 있는 것들을 몇 가지 나열해보자:
C++에는 사실상 필요한 건 거의 다 있다. 솔직히 말하면, 품질은 들쭉날쭉하긴 하다. 그래도 대체로 기대 이상이고, 내가 JavaScript와 Python에서 보는 것보다 나은 편이라고 말하겠다. 사실 "품질 들쭉날쭉"은 모든 언어에 대해 공평하게 할 수 있는 말이다. 진심으로, Python의 패키지 관리가 최고라고 정말 생각하나? 그렇다면 패키지 매니저가 왜 한 10개나 있는 거지? 정말 괜찮은 GUI API가 어느 언어에든 있다고 생각하나? 파일시스템 API는 어떤가? 진짜로, 다들 꽤 형편없다. 그래서 C++의 그것들도 비슷하고, 대부분은 약간 더 낫다고 하겠다. FTXUI 같은 건 놀랍다. STL도 꽤 훌륭하다.
지금쯤 이렇게 말하는 소리가 들린다. "오, 그래, Rust에는 정말 좋은 웹 서버가 있고... 그리고 자료구조도 있고... 그리고.. 어, 어, 어 표준 라이브러리도 있지. Rust도 C++만큼 재밌어!" 그래, 내 요점은 이런 새 기능들이 C++을 재밌게 만든다는 게 아니다. 지금까지의 요점은 이거다:
C++이 오래됐고 지루하며 꺾쇠 괄호, 포인터,
this->같은 허접한 것들로 가득한 언어라고 믿는다면, 그건 틀렸다.
나는 지금 C++이 아마도 현존하는 언어 중 가장 역량이 큰 언어라고 생각한다. 압도적인 격차로 말이다. 못 할 게 없었고, 심지어 하고 싶은 거의 모든 일에 대해 여러 가지 선택지가 존재했다.
이건 몇 가지 예시에 불과하지만, 가장 중요한 포인트는 이거다. C++은 당신을 거의 방해하지 않는다. C나 C++ ABI를 가진 거의 모든 라이브러리, 그리고 모든 운영체제에 직접 접근할 수 있으니, 필요한 건 내가 혼자서도 대부분 만들어낼 수 있다.
좋다. C++로 하고 싶은 건 뭐든 할 수 있고, 2011년 이후 C++ 표준위원회는 개발자 생산성 중심으로 진로를 수정했다. 그래서 그게 어떻게 재미인가요, Zed A. Shaw 씨?
C++은 언어와 생태계의 품질이 매우 높은 한편, 언어 자체는 인기가 덜해서 언어를 망치는 괴짜들을 끌어들이지 않는 아주 이상한 창작의 스윗 스폿에 있다.
누구 얘기인지 알 거다. 내가 C++을 떠난 이유가 디자인 패턴과 템플릿 메타프로그래밍에 미쳐버린 괴짜들 때문이라고 했던 거 기억나나? 그리고 똑같은 일이 Java에서도 디자인 패턴과 미친 XML로 벌어졌다고 농담했지? 그러고는 Ruby on Rails가 뜨자 루비에서도, 그 다음엔 Python, JavaScript, Rust, 그리고 거의 어느 언어든 인기가 많아지면 나타나는, 언어를 망치는 견딜 수 없는 바보들이 또다시 나타났다.
지금 C++은 유행이 아니라서 그 멍청이들이 신경도 안 쓴다. C++은 백악관도 싫어할 정도로 비인기라, 표준 문서로 사람 머리를 내리치는 권위주의적 자칭 인플루언서들—그 사기꾼들—은 자신들의 헛소리를 팔아먹을 수 있는 다른 언어로 도망쳤다.
그 멍청이들은 당신 멘션에 달라붙어 사람들에게 소리친다. "왜 Rust 안 써?!" 그들은 당신을 부끄럽게 만든다. "왜 React 안 써?!" 그들은 소리친다. "Rust 코드에서 왜 unsafe를 그렇게 많이 써?!" 그들은 또 소리친다. "진짜로?! 루비 코드에서 for-루프라니! 헐! 아마추어!" 다행히도 C++은 그 사기꾼들이 이득을 취할 만큼 인기 있지 않아서 대부분 무시한다.
음, 사실 Rust 괴짜들은 귀찮게 굴긴 하지만, 보통은 빌림 검사기 비위를 맞추느라 바빠서 실제로 뭔가를 끝내지 못하니 무시해도 된다.
즉, C++이라는 언어—그리고 C++ 커뮤니티—는 당신이 뭘 하든 그냥 1도 신경 안 쓴다(Does Not Give a Fuck). 행렬 라이브러리를 쓰고 싶다고? 해라. GUI 라이브러리를 만들고 싶다고? 해라. 게임 엔진을 만들고 싶다고? 소파에 앉아 불 꺼놓고 그냥 해라. 당신이 코딩하는 걸 보면서 놀리고 비꼬는 이상한 게임을 만들고 싶다고? 진지하게, 아무도 신경 안 쓰고 대부분은 그걸 웃기거나 재밌다고 생각한다.
"하지만 Zed, 우리에겐 최고의 영도자가 필요하지 않나요? C++에는 권위적인 영원한 자비로운 독재자(BDFL)가 없어서 방향성을 잃는 건가요? 그러다 우리가... 감히 말하건대... 실수라도 하면 어쩌죠?! 비난과 수치심을 팔아먹는 BDFL 사기꾼들이 공짜로 부려먹지 못하게 되면 어떻게 살아남죠?"
아마 정확히 이렇게 말하진 않겠지만, 말의 뉘앙스는 그렇다. 이 사고방식이 다른 언어들이 재미없게 되는 가장 큰 이유 중 하나다. 다른 언어들은 조직에 의해 엄격히 통제되고, 당신이 뭔가 멋진 걸 만들려고 하면 그 조직이 당신을 깐다. BDFL이 이익을 얻는 프로젝트와 경쟁하는 걸 만들려 들면, 그들의 공격견이 몇 년이고 당신을 물어뜯을 준비가 되어 있다.
나는 창의성이 꽃피려면 비난과 수치심에 대한 두려움 없이 아이디어를 밖으로 꺼낼 수 있어야 한다고 굳게 믿는다. 먼저 자신을 표현해야 하고, 그 다음에야 몸부림치며 끄집어낸 아이디어를 한 걸음 물러서 비판적으로 바라봐야 한다. 다만, 아이디어를 세상에 내놓았다면 누군가가 먼저 비판하기 전에 반드시 스스로 비판할 준비를 해야 한다. "비판으로부터의 창작 자유" 모드에서 "품질에 극도로 집중" 모드로 전환하는 이 과정이 훌륭한 창작물을 만든다.
이 개념을 가장 잘 설명해준 건 내가 예전에 다녔던 그림 수업의 선생님이었다. 아니, 사실 내가 만난 모든 그림 선생님들이 그랬다. 그들은 학생의 미완성 작품으로 걸어와 고치려고 들었다. 대개 내 키 6피트2인치와는 다른 자기 키 5피트 높이의 시점으로 서서는, 내 그림이 틀렸다고 성가시게 말한다. 그들의 시점은 내 것과 완전히 다른데도 말이다. 혹은 진행 중인 작품의 어떤 부분을, 완성 그림의 맥락 없이 판단하기 어려운 요소에 대해 지적한다.
이 선생님들의 실수는, 초기에 발생한 "실수"가 과정에서 고쳐질 수 없고 최종 작품에서도 그대로 남을 거라고 가정한 데 있다. 학생이 최종적으로 만든 것이 완성되면 잘 작동하는 경우가 충분히 가능한데, 과정의 한가운데에서는 아무것도 제대로 보이지 않아서 그것을 "고치려는" 시도가 무의미할 수 있다.
이건 그 선생님들이 몰랐던 창의성의 중요한 사실이다. "못생긴 중간 단계"에서는 모든 것이 엉망으로 보이고 느껴진다. 시작할 때는 좋아 보이지만, 작업이 진행되면서 목표하는 최종 비전을 향해 모든 것을 재배치하고 다듬느라 점점 지저분해진다. 자동차 운전이라기보다 줄타기에 가깝다. 반대편으로 갈 수 있도록 아주 가느다란 선 위에서 균형을 잡고 있고, 줄타기는 수없이 떨어져 보면서 균형을 익히는 수밖에 없다.
많은 다른 언어들은, 사람들이 중간에 줄에서 떨어지게 밀쳐버리고는 대신 차를 팔아먹으려는 것처럼 느껴진다.
C++의 거의 무제한에 가까운 창작 공간과, 수치심 장사를 하는 사기꾼이 상대적으로 적다는 사실이 결합해 놀라울 정도로 창의적인 경험을 준다. 아이디어가 있으면 제한 요소는 내 실력뿐이지, 언어의 한계나, 자기 언어의 자비로운 독재자를 좋아하지 않는다는 이유로 나를 가르칠 자격이 없다고 떠드는 C++ 떠벌이 인플루언서 따위가 아니다.
나는 cppreference.com이 내가 써본 최고의 프로그래밍 언어 문서라고 생각한다. 내가 언어 문서에 필요하다고 믿는 거의 모든 걸 가지고 있다. 단 하나를 빼고:
cppreference.com 문서에 유일하게 빠져 있는 건 각 플랫폼에서 다양한 컴파일러를 설치하는 방법이다. 이걸 해야 하는지 말아야 하는지는 나도 반반이다. 다른 언어에는 이런 문서가 매우 중요하지만, C++에서는 아마 여러 집단(기침 *Microsoft* 기침)에게서 반발을 살 것이고, 그래서 못 하는 걸지도 모른다. 하지만 C++ 컴파일러와 플랫폼이 몇 개 안 되는 걸 생각하면, 시작 가이드 몇 편을 추가하는 건 충분히 가능할 것 같다.
C++ 코딩이 미친 듯이 재밌다고 하면서도, 나는 이 언어가 결점이 없다고는 절대 생각하지 않는다. 전혀 그렇지 않다. 내 생각에 C++은 이제 다른 어떤 언어만큼이나 좋아졌고, 완벽한 언어는 없다. 다른 언어에서 그렇듯 C++에도 성가신 것들이 있는데, 단지 C++의 성가심이 다른 언어들과 다를 뿐이다.
예를 들어, C++에서는 비마이크로소프트 설치 프로그램을 Windows에서 잘 돌아가게 하는 게 진짜 지옥같다. 아니요, MSYS2는 안 됩니다. MSYS2는 뜨거운 쓰레기니까 닥치세요. 컴파일러와 개발 도구 설치를 좀 더 쉽게 하려고 아예 PowerShell 스크립트 세트를 만들어야 했다. 그게 끔찍하게 들린다면, 왜 Python을 쓰는가? Windows에서 아무 Python이든 설치해보라. 경로(PATH)에 Python을 추가하지 않는다... 마이크로소프트나 ActiveState에서 축복한 설치 프로그램이 아니라면. 그런 경우에는 PATH에 Python을 추가해도 된다.
여기서 C++이 이긴다. Python처럼 어떤 뒷거래로 Microsoft와 ActiveState만 PATH를 건드려도 되는 유예를 받았네 마네 하는 헛짓거리를 겪을 필요가 없다. 그거 하나만으로도 나에겐 큰 승리다. Python에서 이 상황이 정상적이라고 우기는 멍청이들과 싸워야 하는 건 전혀 재미없다.
당신의 언어가 우월하다고? 1시간만 주면 당신 언어를 한심한 사용성 악몽으로 보이게 만들 만큼의 짜증나는 헛소리를 충분히 찾아내겠다. 다 구리다. 단지 C++의 구림이 재미를 망치지 않는다는 점이 다를 뿐이다.
내가 지금 C++에서 겪는 고통 포인트 몇 가지:
std::source_location에 Clang 버그가 있다고 언급했는데, 이런 류의 쓰레기를 가끔 만나게 되는 좋은 예다. 표준위원회가 이런 버그를 방치하는 컴파일러를 리스트업하기 시작해야 한다고 본다. 간단히, 컴파일러별 표준 준수도를 나열하고, 명백한 버그가 있는 컴파일러를 따로 표시하는 페이지만 있어도 큰 도움이 된다.class 대신 struct를 쓰고 상속은 많이 안 쓰는 새로운 스타일도 보인다. 이 모든 "시대"를 헤엄치는 건 벅차고, 코드 리뷰 유튜버 중엔 어느 한 시대에 갇힌 사람도 적지 않다.하지만 그건 다음 에세이의 주제다. 지금은, 내가 C++로 멍청한 것들을 하면서 얼마나 즐거운지, 그리고 C++이 당신이 아는 그 언어가 아니라는 걸 알리고 싶었다. 만약 꺾쇠 괄호를 억억 개 늘어놓으며 C++을 깎아내리는 강좌를 보게 된다면, 그 강좌 저자는 자기가 무슨 말을 하는지 1도 모르는 얼간이라고 생각해라. 그러니 FXTUI의 이 GUI 레이아웃 코드를 보라:
document_ = Renderer([&]{
return hbox({
hflow(
vbox(
text(format("HP: {}", player_.hp)) | border,
text(status_text_) | border
) | xflex_grow
),
separator(),
hbox(map_view_->Render()),
});
});
솔직히, 이게 C++인지 몰랐다면 무슨 언어인지 맞힐 수 있었나? 더 말할 필요가 없다.