- Dự án Chromium xác định rõ phạm vi sử dụng và các hạng mục bị cấm của những tính năng chuẩn C++ hiện đại để duy trì tính nhất quán của mã nguồn và độ an toàn
- Từ C++11 đến C++23, trạng thái của từng chuẩn được phân loại thành được phép, bị cấm hoặc đang xem xét (TBD), và thư viện Abseil cũng áp dụng cùng tiêu chí này
- Các tính năng bị cấm gồm std::shared_ptr, std::function, std::regex, std::filesystem, std::byte, char8_t, modules cùng nhiều mục khác
- Các tính năng được phép gồm concepts, toán tử spaceship, designated initializer, std::to_underlying, các thuật toán std::ranges
- Hướng dẫn này áp dụng cho toàn bộ Chromium và các dự án con, đóng vai trò là tiêu chuẩn cốt lõi để đảm bảo độ ổn định của mã nguồn và khả năng tương thích khi build
Chính sách sử dụng Modern C++ của Chromium
- Chromium không đưa ngay các chuẩn C++ mới nhất vào sử dụng, mà chỉ gắn trạng thái được hỗ trợ ban đầu (initially supported) sau khi mức hỗ trợ của toolchain đã đủ vững
- Sau đó, từng tính năng sẽ được phân loại thành được phép (allowed), bị cấm (banned) hoặc đang xem xét (TBD)
- Việc đề xuất thay đổi trạng thái của các tính năng mới có thể được gửi qua mailing list cxx@chromium.org
- Sau 2 năm kể từ khi được hỗ trợ ban đầu, tính năng sẽ được xem xét rõ ràng để chuyển sang danh sách được phép hoặc bị cấm
Các tính năng bị cấm trong C++11
- Tính năng ngôn ngữ: inline namespace, long long, user-defined literals
- Tính năng thư viện:
<chrono>, <regex>, <random> engine, <exception>, <ratio>, <thread> v.v.
- Exception bị vô hiệu hóa hoàn toàn, chỉ cho phép
noexcept
- Thay vì
std::bind, std::function, std::shared_ptr, std::weak_ptr, Chromium dùng base::Bind, base::Callback, base::RefCounted
Các tính năng bị cấm trong C++17
- Cấm literal ký tự UTF-8 (u8) do vấn đề tương thích với
char8_t
- Các mục thư viện bị cấm:
- Hàm toán học đặc biệt, thuật toán song song (parallel algorithms),
std::any, std::byte, std::filesystem, tài nguyên bộ nhớ std::pmr v.v.
- Thuật toán song song bị cấm vì libc++ chưa hỗ trợ và có lo ngại xung đột với mô hình luồng của Chrome
Các tính năng được phép và bị cấm trong C++20
- Các tính năng ngôn ngữ được phép:
- concepts, consteval, designated initializers, toán tử spaceship, [[likely]], cú pháp khởi tạo trong range-for
- Các tính năng thư viện được phép:
<bit>, <compare>, <concepts>, <numbers>, std::erase_if, std::ranges::subrange, std::to_underlying v.v.
- Các tính năng bị cấm:
- char8_t, modules, [[no_unique_address]],
std::bit_cast, <span>, std::bind_front, std::ranges::view_interface
- Đang xem xét (TBD): coroutine,
<format>, <source_location>, std::u8string
Các tính năng được phép và đang xem xét trong C++23
- Các tính năng ngôn ngữ được phép:
#elifdef, if consteval, static operator
- Các tính năng thư viện được phép:
std::byteswap, std::basic_string::contains, std::to_underlying, các thuật toán mở rộng của std::ranges
- Các tính năng đang xem xét:
std::expected, std::mdspan, std::generator, std::stacktrace, std::print, [[assume]], #warning v.v.
Chính sách với thư viện Abseil
- Các thành phần Abseil bị cấm:
absl::any, absl::optional, absl::StatusOr, absl::Span, absl::FunctionRef, absl::Mutex, absl::Time, absl::btree_* v.v.
- Phần lớn được thay thế bằng các triển khai trong namespace base của Chromium (
base::span, base::expected, base::Bind v.v.)
- Đang xem xét (TBD):
absl::linked_hash_set, absl::linked_hash_map
Ý nghĩa tổng thể
- Chromium không chấp nhận vô điều kiện các tính năng C++ chuẩn, mà chọn lọc áp dụng dựa trên độ ổn định khi build, bảo mật, hiệu năng và tính nhất quán của mã nguồn
- Phần lớn các tính năng bị cấm là do đã có triển khai trùng lặp (base::) hoặc vấn đề tương thích toolchain và ABI
- Hướng dẫn này là bộ tiêu chuẩn quản lý chất lượng mã C++ trong hệ sinh thái Chromium, đồng thời là tài liệu tham chiếu thiết yếu khi cộng tác mã nguồn mở
3 bình luận
Thật tiếc là vì tính tương thích ngược, ngôn ngữ C++ cứ ngày càng phình to hơn..
Đúng là một ngôn ngữ khổng lồ, đúng như điều người ta nói trong các ý kiến trên HN về C++ ...
Ý kiến Hacker News
Không có gì đặc biệt nổi bật, nhưng phần lớn nội dung kiểu như “hãy dùng thư viện tự xây dựng trong nội bộ cho đúng mục đích của chúng ta”
Phần còn lại cũng khá hợp lý, như tránh các vấn đề về locale. Cũng dễ hiểu vì có những lựa chọn để làm mượt các góc cạnh thô ráp của thư viện chuẩn
chrononên họ tự tạo kiểu thời gian riêng, và đã dùng container riêng từ trước khi STL ổn địnhNếu bắt đầu một dự án mới bây giờ thì có lẽ phần lớn các quy tắc này không còn nhiều ý nghĩa
char8_tkhá thú vị. Gần như không còn mấy encoding không phải UTF-8, vàchar8_t*không tương thích vớichar*, nên họ khuyến nghị dùngstd::stringhoặcstd::string_viewđể tránh tràn lan ép kiểuNói đến code cũ lại làm tôi nhớ thời Chromium mới ra mắt
Thật đáng ngạc nhiên khi nhận ra codebase này đã được bắt đầu từ 20 năm trước
Cấm
<regex>là quyết định đúng đắn. Nó không xử lý UTF-8 đúng cách nên gần như không dùng được. Thật lạ khi một thiết kế có khuyết điểm như vậy lại được chuẩn hóaỞ thư mục cấp trên còn có những tài liệu thú vị hơn
Chromium C++ Style Guide là tài liệu đáng tham khảo
Exception bị cấm, nhưng Windows là ngoại lệ duy nhất
Họ không cấm vì phản đối exception về mặt triết học, mà vì lý do thực dụng. Họ nói rằng nếu làm lại từ đầu thì có lẽ đã chọn khác
[[no_unique_address]], nên chắc là tôi đã bỏ lỡ một câu đùaDanh sách tính năng bị cấm quá nhiều, trông còn nhiều hơn toàn bộ tính năng của C. Quá choáng ngợp
Cấm literal
u8"..."là quyết định hợp lý. Nếu bản thân mã nguồn đã viết bằng UTF-8 thì đâu cần tiền tố riêngKiểu literal này là trường hợp giải pháp xuất hiện trước cả vấn đề
Tôi muốn tìm cách thay thế cho các tính năng bị cấm. Ví dụ,
<filesystem>bị nói là thiếu hỗ trợ cho kiểm thử và có lỗ hổng bảo mật<filesystem>là ngoại lệbase/filesModules cũng bị cấm. Giá mà họ sao chép luôn hệ thống module của ngôn ngữ D thì có lẽ tốt hơn
Danh sách cấm này cho thấy “bối cảnh quan trọng hơn các tính năng mới”. Với ứng dụng nhỏ thì không sao, nhưng trong dự án quy mô lớn thì sẽ rất rủi ro
Tính di động giữa nhiều nền tảng cũng là yếu tố được cân nhắc