- C++26 đã chính thức hoàn tất về mặt kỹ thuật. Gồm bốn tính năng cốt lõi: reflection, tăng cường an toàn bộ nhớ, Contracts, std::execution
- Compile-time reflection là động cơ trừu tượng hóa mạnh mẽ nhất trong lịch sử C++ kể từ khi template ra đời, cho phép ngôn ngữ tự mô tả chính nó và sinh mã
- Chỉ cần biên dịch lại mã C++ hiện có bằng C++26 là có thể loại bỏ hành vi không xác định (UB) do biến cục bộ chưa khởi tạo, đồng thời thư viện chuẩn được tăng cường đảm bảo an toàn bounds
- Theo kết quả triển khai tại Google, đã sửa hơn 1.000 lỗi và ghi nhận mức giảm 30% segfault trong môi trường production
- Dự kiến các trình biên dịch sẽ nhanh chóng tiếp nhận, khi GCC đã hợp nhất reflection và contracts vào trunk
C++26 hoàn tất: Bản phát hành quan trọng nhất kể từ C++11
- Tại cuộc họp ủy ban ISO C++ tổ chức ở Croydon, London, Vương quốc Anh, công việc kỹ thuật của C++26 đã được hoàn tất cuối cùng
- Khoảng 210 người tham dự (130 trực tiếp, 80 từ xa qua Zoom), với đại diện chính thức từ 24 quốc gia
- Phần lớn thời lượng cuộc họp được dành để xử lý 411 bình luận quốc tế (giai đoạn CD) được gửi trong mùa hè
- Tập trung vào hoàn thiện chi tiết cuối cùng (fit-and-finish), không thêm hay loại bỏ tính năng mới
- C++26 được chốt tại kỳ họp này đã bước vào giai đoạn chuẩn bị tài liệu cuối cùng cho bỏ phiếu phê duyệt quốc tế (DIS)
4 tính năng cốt lõi của C++26
(1) Reflection
- Đây là bản nâng cấp lớn nhất trong lịch sử phát triển C++ kể từ khi template được phát minh, cho phép ngôn ngữ tự mô tả chính nó và sinh mã
- Vào tháng 6/2025, ủy ban C++ đã đưa compile-time reflection vào bản nháp C++26, đánh dấu bước ngoặt trong lịch sử ngôn ngữ
- Tính năng này được giới thiệu là "động cơ mới mạnh mẽ nhất để biểu đạt các trừu tượng hiệu quả, và sẽ cần thêm 10 năm nữa để khám phá hết tên lửa này có thể làm được gì"
(2) Tăng cường an toàn bộ nhớ
- Chỉ cần biên dịch lại, toàn bộ nhóm UB do đọc biến cục bộ chưa được khởi tạo trong mã C++ hiện có sẽ được loại bỏ trong C++26
- Hardened Standard Library đã được chuẩn hóa, đảm bảo an toàn bounds cho các kiểu quan trọng như vector, span, string, string_view
- Mức overhead hiệu năng đo được trung bình chỉ 0,3% (dưới 1%)
- Đã được triển khai trên hàng trăm triệu dòng mã tại nền tảng Apple và các dịch vụ của Google
- Các số liệu từ triển khai tại Google:
- Đã sửa hơn 1.000 lỗi
- Dự kiến ngăn chặn 1.000~2.000 lỗi mỗi năm
- Tỷ lệ segfault giảm 30% trên toàn bộ production
- Trong toàn bộ mã C++ của Google, chỉ có 5 dịch vụ opt-out hoàn toàn và chỉ 7 vị trí dùng API truy cập không an toàn
(3) Contracts: pre, post, contract_assert
- C++26 đưa vào tính năng contracts ở cấp ngôn ngữ — hỗ trợ precondition, postcondition và câu lệnh assertion trong khai báo hàm
- Được đánh giá là mạnh hơn rất nhiều so với macro assert của C
- Kết quả bỏ phiếu khi thông qua contracts:
- Tháng 2/2025 (hợp nhất vào working draft): 100 phiếu thuận, 14 phiếu chống, 12 phiếu trắng
- Tháng 3/2026 (chốt cuối cùng cho C++26): 114 phiếu thuận, 12 phiếu chống, 3 phiếu trắng
- Dù một số chuyên gia trong ủy ban vẫn tiếp tục nêu lo ngại kỹ thuật, chủ đề này đã được thảo luận đầy đủ qua 3 kỳ họp và nhiều cuộc họp điện thoại
- Trước kỳ họp tháng 11/2025, đã hoàn tất sửa 2 lỗi trong đặc tả contracts để phản ánh phản hồi
(4) std::execution (Sender/Receiver)
- Đây là mô hình bất đồng bộ của C++, một framework thống nhất để biểu đạt và kiểm soát tính đồng thời cùng song song
- Cho phép viết structured concurrency (mô hình đồng thời có vòng đời lồng nhau chặt chẽ) dễ dàng hơn, từ đó có đặc tính an toàn giúp ngăn data race về mặt cấu trúc
- Lưu ý: hiện tài liệu còn thiếu và hệ sinh thái thư viện "fingers-and-toes" còn chưa đầy đủ, nên mức độ khó khi áp dụng cao hơn các tính năng C++ khác
- Có thể cần sự hỗ trợ của chuyên gia đã quen thuộc với mô hình này, cũng như cần viết thư viện adapter để tích hợp với mã bất đồng bộ hiện có
Vì sao C++26 được kỳ vọng sẽ được tiếp nhận nhanh chóng
- Đây là bộ tính năng được mong đợi nhất kể từ C++11, vì bao gồm reflection và tăng cường an toàn — những thứ đa số lập trình viên C++ sẽ dùng hằng ngày
- Các tính năng như Parallel STL, concepts, coroutines, modules trong C++17, C++20, C++23 được đánh giá là chưa tạo ảnh hưởng rộng đến mọi lập trình viên C++ như C++11
- GCC và Clang trong suốt quá trình phát triển C++26 đã duy trì trạng thái triển khai sẵn trước khoảng hai phần ba số tính năng
- GCC đã hợp nhất reflection và contracts vào trunk, chỉ còn chờ phát hành
Bắt đầu công việc cho C++29: đào sâu an toàn bộ nhớ
- Tại kỳ họp này, lịch trình C++29 cũng đã được thông qua, tiếp tục chu kỳ phát hành 3 năm
- Trọng tâm chính của C++29 được xác định là tăng cường hơn nữa an toàn kiểu và an toàn bộ nhớ
- Đang xem xét các đề xuất nhằm tiếp tục giảm hành vi không xác định (UB)
- SG23 (nhóm con về an toàn và bảo mật) đang làm việc dựa trên P3984 hồ sơ an toàn kiểu của Bjarne Stroustrup và framework hồ sơ tổng quát của Gabriel Dos Reis
- Oliver Hunt của Apple đã trình bày P4158R0 "Subsetting and Restrictions for C++ for Memory Safety"
- Áp dụng cách tiếp cận subset-of-superset cho hơn 4 triệu dòng mã của WebKit
- Báo cáo cho biết cách này "chặn được nhiều lớp lỗ hổng và chính sách hiện tại lẽ ra đã ngăn phần lớn các exploit trong quá khứ"
- Chủ đề an toàn bộ nhớ đã được thảo luận chuyên sâu tại phiên tối thứ Tư với hơn một nửa ủy ban tham dự và phiên EWG chuyên đề chiều thứ Sáu với khoảng 90 người tham gia
- Thư viện quantities and units (P3045R7 "Quantities and units library") đã tiến từ SG6·SG18 lên LEWG (nhóm con tiến hóa thư viện chính)
Lịch trình sắp tới
- Hai kỳ họp tiếp theo sẽ được tổ chức tại Brno, CH Czech (tháng 6) và Búzios, Rio de Janeiro, Brazil (tháng 11)
- Trong hai kỳ họp này sẽ bắt đầu bổ sung tính năng vào working draft của C++29
- Từ nay đến trước kỳ họp tiếp theo, nhiều buổi telecon của các nhóm con đã được lên lịch
6 bình luận
zzz
Ý kiến trên Hacker News
Thật đáng tiếc khi tính năng Contracts đã được đưa vào chuẩn của C++
Cảm giác như lại bổ sung thêm một lớp phức tạp nữa vào một ngôn ngữ vốn đã chạm tới giới hạn về độ phức tạp
Ngay cả Bjarne Stroustrup cũng gọi tính năng này là "một thiết kế chưa hoàn thiện và bị thổi phồng theo kiểu ủy ban"
Tôi cũng cho rằng bản thân tính năng này có quá nhiều yếu tố nguy hiểm (footgun), nên khó thấy được tính chính đáng của nó
Nhưng chẳng ai tỏ ra quan tâm
Tài liệu liên quan có ở đây
Đây là yếu tố cốt lõi để tích hợp với kiểm chứng hình thức (proof assistant) như Ada hay Rust, cho phép xác minh tĩnh thay cho kiểm thử
Có thể tham khảo Ada Spark
Ví dụ đầu tiên trong tài liệu cppreference lại là một trường hợp ngoại lệ có thay đổi trạng thái
Cú pháp cũng không trực quan
Ví dụ, dạng như
asserts_pre(num >= 0)sẽ rõ ràng hơn nhiều so vớipre(num >= 0)Nhưng có vẻ họ ưu tiên sự ngắn gọn
Thay vì làm tăng thêm độ phức tạp, nó là hướng hợp nhất những cách mỗi người tự triển khai để cải thiện khả năng tương tác
Ngược lại, tôi cho rằng những tính năng như Reflection mới là thứ làm tăng độ phức tạp hơn
Với tư cách là một lập trình viên C# và Java, tôi có một điều muốn hỏi
Dạo này người ta dùng C++ để làm những loại ứng dụng nào?
Tôi hiếm khi có cơ hội nghe về việc nó thực sự đang giải quyết những vấn đề gì
Việc định nghĩa lại “erroneous behavior” cho biến chưa khởi tạo khá thú vị
Theo tài liệu chuẩn, điều này tạo ra chi phí runtime,
và có thể chuyển lại thành undefined behavior bằng thuộc tính
[[indeterminate]]Nếu thực sự không muốn khởi tạo thì phải viết rõ ràng như
int x = void;Gần như không thể vô tình viết như vậy
[[indeterminate]]lại quay về UB (Undefined Behavior)Một số dự án có thể vẫn sẽ thích khởi tạo thủ công
[[indeterminate]]trong code mà thấy kinh khủngCuối cùng họ либо sẽ mất thời gian đi tra ý nghĩa của nó, hoặc về sau просто mặc kệ
Điều này làm tôi nhớ đến trải nghiệm đọc code Rust với quá nhiều generic và trait khiến rất khó theo dõi
Tôi từng làm ở đội C++ của Microsoft vào những năm 90
Khi đó tôi nghĩ RTTI đã là giới hạn của hệ thống phản chiếu (reflection) mà C++ có thể có
Sự phát triển bây giờ thật đáng kinh ngạc
Việc tổ chức cuộc họp ở Croydon rồi không cho ai rời đi cho tới khi ký tên đúng là một chiến thuật khá khôn khéo
Tôi không muốn làm việc ở đó thêm lần nào nữa
Tôi tò mò về tình trạng triển khai C++26 của GCC và Clang
GCC đã hợp nhất reflection và contracts vào trunk rồi, nhưng không rõ Clang đang ở mức nào
còn trang của GCC thì ghi “yes”
Nó đã dùng được trên Compiler Explorer, và đang được tận dụng để bổ sung reflection cho simdjson
Tôi nghi ngờ những thay đổi ở hệ thống module trong chuẩn lần này có thực sự khiến nó được dùng rộng rãi hơn không
Đó chính là lý do Cargo của Rust vượt xa C++
Việc không thể chỉ dùng một dòng
cargo addđể thêm dependency đang khiến thế hệ mới tránh xa nóNếu CMake áp dụng mô hình biên dịch 2 giai đoạn của Clang thì tốc độ build sẽ được cải thiện đáng kể,
và khi đó module mới thực sự bắt đầu được chấp nhận rộng rãi
Gần như không có khả năng trở thành dòng chính
Có quá nhiều tính năng mới nên rất khó theo kịp
Hệ thống build cũng lộn xộn, và file header thì giờ đáng ra phải biến mất rồi
Hơi lệch chủ đề, nhưng cách nói “London Croydon” nghe khá lạ
Bình thường chẳng phải nên nói “Croydon, London” sao?
Khi lên kế hoạch du lịch, đọc từ khu vực lớn tới khu vực nhỏ thường tự nhiên hơn
Có lẽ họ viết “London, Croydon” để tạo cảm giác là “cuộc họp diễn ra ở London”
“Croydon, London” lại nghe giống “diễn ra ở Croydon, vùng ngoài London”, nên kém sang hơn — một cách diễn giải nửa đùa nửa thật
Cũng có những phản ứng mỉa mai kiểu như “nó ra đời đúng lúc ngay trước khi ngôn ngữ này bị khai tử”
Nếu C++29 chỉ tập trung vào cải thiện chất lượng và gọt giũa các tính năng hiện có thì có lẽ cộng đồng cũng sẽ không quá bất mãn
Thay vì bổ sung thêm tính năng để đảm bảo an toàn bộ nhớ, chỉ cần không cho phép con trỏ treo hoặc tham chiếu có thể thay đổi thì an toàn bộ nhớ cũng đã được cải thiện, vậy mà họ lại chỉ làm tăng độ phức tạp của mã bằng cách thêm tính năng.
Tôi đã rất vất vả mới chuyển sang Rust, nên việc khá nhiều tính năng tôi từng chờ đợi đã được đưa vào bản tiêu chuẩn C++26 đúng là đáng khích lệ. Nhưng tôi sẽ không quay lại C++ đâu... haha
Phần liên quan đến đóng gói cũng đang được phía CMake đưa ra..
https://www.kitware.com/common-package-specification-is-out-the-gate/
contractđúng là tính năng tôi đã chờ đợi bấy lâu, cuối cùng cũng đã có