C++26 완성! — C++11 이후 최대 업그레이드, 리플렉션과 메모리 안전성 강화 공식 확정
(herbsutter.com)- C++26이 공식 기술 완료. 리플렉션, 메모리 안전성 강화, 계약(Contracts), std::execution 등 네 가지 핵심 기능이 포함됨
- 컴파일 타임 리플렉션은 템플릿 도입 이래 C++ 역사상 가장 강력한 추상화 엔진으로, 언어가 스스로를 기술하고 코드를 생성할 수 있게 됨
- 기존 C++ 코드를 C++26으로 재컴파일만 해도 초기화되지 않은 지역 변수의 미정의 동작(UB)이 제거되며, 강화된 표준 라이브러리로 bounds 안전성이 보장됨
- Google에서의 배포 결과, 1,000개 이상의 버그 수정과 프로덕션 환경에서의 segfault 30% 감소 효과가 실측됨
- GCC가 이미 리플렉션과 계약 기능을 trunk에 병합 완료하는 등 컴파일러 구현체들의 빠른 채택이 예상됨
C++26 완성: C++11 이후 가장 중요한 릴리스
- 영국 런던 크로이던에서 열린 ISO C++ 위원회 회의에서 C++26 기술 작업이 최종 완료됨
- 약 210명 참석 (대면 130명, Zoom 원격 80명), 24개국 공식 대표 참여
- 여름에 접수된 411건의 국제 코멘트(CD 단계) 를 처리하는 데 회의 대부분을 할애
- 새 기능 추가 및 제거 없이 완성도 보완(fit-and-finish)에 집중
- 이번 회의에서 마무리된 C++26은 국제 승인 투표(DIS) 를 위한 최종 문서 작성 단계에 진입
C++26의 4대 핵심 기능
(1) 리플렉션 (Reflection)
- 템플릿 발명 이래 C++ 개발 역사상 가장 큰 업그레이드로, 언어가 자기 자신을 기술하고 코드를 생성할 수 있는 기능
- 2025년 6월 C++ 위원회는 컴파일 타임 리플렉션을 C++26 초안에 포함시키며 언어 역사의 전환점을 기록
- "효율적인 추상화를 표현하기 위한 가장 강력한 새 엔진이며, 이 로켓이 무엇을 할 수 있는지 발견하는 데 앞으로 10년이 필요할 것"이라고 소개됨
(2) 메모리 안전성 강화
- 재컴파일만으로 기존 C++ 코드에서 초기화되지 않은 지역 변수 읽기의 UB(미정의 동작) 전체 범주가 C++26에서 제거됨
-
강화된 표준 라이브러리(Hardened Standard Library) 가 표준화되어 vector, span, string, string_view 등 주요 타입의 bounds 안전성 보장
- 성능 오버헤드 평균 0.3% (1% 미만)로 실측됨
- Apple 플랫폼과 Google 서비스에서 수억 줄 코드에 이미 배포 완료
- Google 배포 결과 수치:
- 1,000개 이상의 버그 수정 완료
- 연간 1,000~2,000건의 버그 예방 효과 전망
- 프로덕션 전체에서 segfault 발생률 30% 감소
- 전체 Google C++ 코드 중 전면 opt-out 서비스는 단 5개, 안전하지 않은 접근 API 사용은 7곳에 불과
(3) 계약(Contracts): pre, post, contract_assert
- C++26에서 언어 수준의 계약 기능 도입 — 함수 선언의 사전조건(precondition), 사후조건(postcondition) 및 assertion 문 지원
- C의 assert 매크로보다 훨씬 강력한 기능으로 평가됨
- 계약 채택 시 투표 결과:
- 2025년 2월 (working draft 병합): 찬성 100, 반대 14, 기권 12
- 2026년 3월 (C++26 최종 확정): 찬성 114, 반대 12, 기권 3
- 일부 위원회 전문가들의 기술적 우려가 지속되었으나, 3차례의 회의와 다수의 전화회의에서 충분히 논의됨
- 2025년 11월 이전 회의에서 피드백을 반영해 계약 스펙의 버그 2건 수정 완료
(4) std::execution (Sender/Receiver)
- C++의 비동기 모델로, 동시성과 병렬성을 표현·제어하는 통합 프레임워크
- structured concurrency(엄격하게 생명주기가 중첩된 동시성)를 쉽게 작성하게 해 데이터 경쟁(data race)을 구조적으로 방지하는 안전성 특성 보유
-
주의: 현재 문서화가 부족하고 "fingers-and-toes" 라이브러리가 미흡해 채택 난이도가 다른 C++ 기능들보다 높음
- 이미 잘 아는 전문가의 도움 및 기존 비동기 코드와의 연동을 위한 어댑터 라이브러리 작성이 필요할 수 있음
C++26의 빠른 채택이 예상되는 이유
-
C++11 이후 가장 수요가 높은 기능 세트로, 대다수 C++ 개발자가 일상적으로 활용할 리플렉션과 안전성 강화가 포함됨
- C++17, C++20, C++23의 병렬 STL, 개념(concepts), 코루틴, 모듈 등은 모든 C++ 개발자에게 C++11만큼 광범위한 영향을 주지 못했다는 평가
- GCC와 Clang은 C++26 개발 전반에 걸쳐 기능의 3분의 2를 사전 구현 완료 상태를 유지해 왔음
- GCC는 이미 리플렉션과 계약을 trunk에 병합 완료, 출시 대기 중
C++29 작업 시작: 메모리 안전성 심화
- 이번 회의에서 C++29 일정도 채택, 3년 주기 릴리스 사이클 유지
- C++29의 주요 초점은 타입·메모리 안전성 추가 강화로 확정됨
- 미정의 동작(UB) 추가 감소 제안들 검토 중
- SG23(안전·보안 서브그룹)에서 Bjarne Stroustrup의 P3984 타입 안전성 프로파일 및 Gabriel Dos Reis의 일반 프로파일 프레임워크를 기반으로 작업 진행 중
- Apple의 Oliver Hunt가 P4158R0 "메모리 안전성을 위한 C++ 서브셋팅과 제한" 발표
- WebKit의 400만 줄 이상의 코드에 subset-of-superset 접근 방식 적용
- "다수의 취약점 클래스를 차단하며, 현재 정책이 과거 대부분의 익스플로잇을 방지했을 것"이라고 보고됨
- 메모리 안전성 주제는 위원회 과반이 참석한 수요일 저녁 세션과 약 90명이 참석한 금요일 오후 EWG 전용 세션에서 심도 있게 논의됨
- 수량·단위 라이브러리(P3045R7 "Quantities and units library") 가 SG6·SG18에서 LEWG(메인 라이브러리 진화 서브그룹)로 진척됨
향후 일정
- 다음 두 차례 회의는 체코 브르노(6월) 및 브라질 리우데자네이루 부지우스(11월) 에서 개최 예정
- 두 회의에서 C++29 working draft에 기능 추가 작업 시작
- 지금부터 다음 회의 전까지 다수의 서브그룹 텔레콘(화상 회의)이 이미 일정에 포함됨
Hacker News 의견들
-
C++에 Contracts 기능이 표준으로 채택된 것이 아쉬움
이미 복잡성이 한계에 도달한 언어에 또 다른 복잡성을 더하는 느낌임
Bjarne Stroustrup도 이 기능을 “불완전하고 위원회식으로 부풀려진 설계” 라고 표현했음
기능 자체의 위험 요소(footgun)도 많아 정당성이 부족하다고 생각함- 90년대 초에 C++에 Contracts 확장을 직접 구현했었음
하지만 아무도 관심을 보이지 않았음
관련 자료는 여기에 있음 - 많은 사람들이 “C++은 너무 복잡하다”고 말하지만, 각자 떠올리는 복잡한 기능이 다 다르다는 점이 흥미로움
- C++의 Contracts 설계가 잘못됐을 수도 있지만, 개념 자체는 언어 발전에 꼭 필요하다고 생각함
Ada나 Rust처럼 정형 검증(proof assistant) 과 통합되어 테스트 대신 정적 검증을 가능하게 하는 핵심 요소임
Ada Spark를 참고할 만함 - Contracts에 대한 문서가 너무 혼란스러움
cppreference 문서의 첫 예시는 오히려 상태를 변경하는 예외적인 케이스임
문법도 직관적이지 않음
예를 들어asserts_pre(num >= 0)같은 형태가pre(num >= 0)보다 훨씬 명확했을 것임
하지만 간결함이 우선된 듯함 - Contracts는 이미 C++ 개발자들이 비공식적으로 해오던 일을 표준화한 것임
복잡성을 더한다기보다는, 각자 구현하던 것을 통합해 상호운용성을 높이는 방향임
오히려 Reflection 같은 기능이 더 복잡성을 추가한다고 봄
- 90년대 초에 C++에 Contracts 확장을 직접 구현했었음
-
C#, Java 개발자로서 궁금한 점이 있음
C++로 요즘 어떤 종류의 애플리케이션을 만드는지 알고 싶음
실제로 어떤 문제를 해결하는지 잘 들을 기회가 없음 -
초기화되지 않은 변수의 “erroneous behavior” 재정의가 흥미로움
표준 문서에 따르면 런타임 비용이 생기며,
[[indeterminate]]속성을 사용하면 다시 undefined behavior로 돌릴 수 있음int x [[indeterminate]]; std::cin >> x;- D 언어는 모든 변수를 자동으로 초기화함
정말 초기화하지 않으려면int x = void;처럼 명시적으로 써야 함
실수로 그렇게 작성할 일은 거의 없음 - 문서를 빠르게 읽어보니 두 가지가 놀라움
- “독립적으로 결정된 값”이란 게 정확히 무엇을 의미하는지 불분명함 — 0으로 채우는 건지, 메모리의 임의 값인지?
-
[[indeterminate]]가 왜 다시 UB(Undefined Behavior) 로 돌아가는지 의문임
- 아마도 이 기능은 컴파일러 플래그로 제어할 수 있을 듯함
일부 프로젝트는 여전히 수동 초기화를 선호할 것임 - 나중에 코드에서
[[indeterminate]]를 보게 될 사람을 생각하면 끔찍함
결국 의미를 찾아보느라 시간을 낭비하거나, 나중엔 그냥 무시하게 될 것임
Rust에서 제너릭과 트레잇이 너무 많아 코드 읽기 힘들었던 경험이 떠오름
- D 언어는 모든 변수를 자동으로 초기화함
-
90년대 MS의 C++ 팀에서 일했었음
그때는 RTTI가 C++이 가질 수 있는 반사(reflection) 시스템의 한계라고 생각했음
지금의 발전이 놀라움 -
Croydon에서 회의를 열고, 서명할 때까지 아무도 못 나가게 한 건 꽤 교묘한 전략이었음
다시는 거기서 일하고 싶지 않음 -
GCC와 Clang의 C++26 구현 상황이 궁금했음
GCC는 이미 reflection과 contracts를 trunk에 병합했지만, Clang은 어느 정도인지 알고 싶음-
Clang 상태 페이지에는 둘 다 “no”,
GCC 페이지에는 “yes”로 표시되어 있음 - Bloomberg가 Clang용 reflection 구현을 여기에 공개했음
이미 Compiler Explorer에서도 사용 가능하며, simdjson에 reflection을 추가하는 데 활용됨
-
Clang 상태 페이지에는 둘 다 “no”,
-
이번 표준의 모듈 시스템 변경이 실제로 더 널리 쓰이게 만들지 의문임
- C++ WG가 한 번쯤은 새 기능보다 모듈과 패키징에 집중해야 한다고 생각함
Rust의 Cargo가 C++을 압도하는 이유가 바로 그 부분임
cargo add한 줄로 의존성을 추가할 수 없다는 점이 새 세대를 멀어지게 함 - 대부분의 컴파일러가 아직 header unit을 지원하지 않음
Clang의 2단계 컴파일 모델을 CMake가 채택하면 빌드 속도가 크게 개선될 것이고,
그때야 비로소 모듈이 본격적으로 채택될 것임 - 모듈은 이미 실패한 아이디어라고 생각함
주류로 자리 잡을 가능성이 거의 없음 - 솔직히 이제는 C++ 개발을 멈췄으면 함
새로운 기능이 너무 많아 따라가기 힘듦
빌드 시스템도 엉망이고, 헤더 파일은 이제 사라져야 함
- C++ WG가 한 번쯤은 새 기능보다 모듈과 패키징에 집중해야 한다고 생각함
-
주제와는 다르지만, “London Croydon”이라는 표현이 이상하게 들림
보통 “Croydon, London”이라고 하지 않나?- “London Gatwick Airport”처럼 일반적인 역순 표현도 존재함
여행 계획을 세울 때는 큰 지역부터 작은 지역 순으로 읽는 게 더 자연스러움 - 사람마다 구체적인 것부터 말하느냐, 일반적인 것부터 말하느냐가 다름
“London, Croydon”이라고 쓴 이유는 아마도 “런던에서 회의했다”는 인상을 주기 위해서일 것임
“Croydon, London”은 “런던 외곽의 Croydon에서 했다”는 느낌이라 덜 멋져 보임 — 농담 섞인 해석임
- “London Gatwick Airport”처럼 일반적인 역순 표현도 존재함
-
“언어 폐기 직전에 맞춰 나왔다”는 식의 냉소적인 반응도 있음
-
C++29가 품질 개선과 기존 기능 다듬기에만 집중한다면 커뮤니티도 크게 불만 없을 것 같음
- 개인적으로는 C++29에서 한 줄짜리 random() 함수만 생겨도 만족할 것임
- 물론 어떤 기능이 추가되느냐에 따라 커뮤니티 반응은 달라질 것임