https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md Modern C++ use in Chromium This document is part of the more general Chromium C++ style guide. It summarizes the supported state of new and updated language and library features in recent C++ standards and the Abseil library. This guide applies to both Chromium and its subprojects, though subprojects can choose to be more restrictive if necessary for toolchain support. The C++ language has in recent years received an updated standard every three years (C++11, C++14, etc.). For various reasons, Chromium does not immediately allow new features on the publication of such a standard. Instead, once Chromium supports the toolchain to a certain extent (e.g., build support is ready), a standard is declared " initially supported", with new language/library features banned pending discussion but not yet allowed. You can propose changing the status of a feature by sending an email to cxx@chromium.org. Include a short blurb on what the feature is and why you think it should or should not be allowed, along with links to any relevant previous discussion. If the list arrives at some consensus, send a codereview to change this file accordingly, linking to your discussion thread. If an item remains on the TBD list two years after initial support is added, style arbiters should explicitly move it to an appropriate allowlist or blocklist, allowing it if there are no obvious reasons to ban. The current status of existing standards and Abseil features is: * C++11: Default allowed; see banned features below * C++14: Default allowed * C++17: Default allowed; see banned features below * C++20: Initially supported November 13, 2023; see allowed/banned/ TBD features below * C++23: Initially supported January 2026; see allowed/banned/TBD features below * C++26: Not yet supported * Abseil: Default allowed; see banned/TBD features below. The following dates represent the start of the two-year TBD periods for certain parts of Abseil: + absl::linked_hash_set & map: Initially added to third_party Dec 30, 2025 Banned features and third-party code Third-party libraries may generally use banned features internally, although features with poor compiler support or poor security properties may make the library unsuitable to use with Chromium. Chromium code that calls functions exported from a third-party library may use banned library types that are required by the interface, as long as: * The disallowed type is used only at the interface, and converted to and from an equivalent allowed type as soon as practical on the Chromium side. * The feature is not banned due to security issues or lack of compiler support. If it is, discuss with cxx@chromium.org to find a workaround. Contents * Banned features and third-party code * C++11 Banned Language Features + Inline Namespaces [banned] + long long Type [banned] + User-Defined Literals [banned] * C++11 Banned Library Features + , , , [banned] + , [banned] + [banned] + [banned] + Engines And Generators From [banned] + [banned] + [banned] + std::aligned_{storage,union} [banned] + std::bind [banned] + std::function [banned] + std::shared_ptr [banned] + std::{sto{i,l,ul,ll,ull,f,d,ld},to_string} [banned] + std::weak_ptr [banned] + Thread Support Library [banned] * C++17 Banned Language Features + UTF-8 character literals [banned] * C++17 Banned Library Features + Mathematical special functions [banned] + Parallel algorithms [banned] + std::aligned_alloc [banned] + std::any [banned] + std::byte [banned] + std::filesystem [banned] + std::{from,to}_chars [banned] + std::{pmr::memory_resource,polymorphic_allocator} [banned] + std::timespec_get [banned] + std::uncaught_exceptions [banned] + Transparent std::owner_less [banned] + weak_from_this [banned] * C++20 Allowed Language Features + Abbreviated function templates [allowed] + consteval [allowed] + Constraints and concepts [allowed] + Default comparisons [allowed] + Designated initializers [allowed] + __has_cpp_attribute [allowed] + constinit [allowed] + Initializers for bit-field members [allowed] + Lambda captures with initializers that are pack expansions [allowed] + Language feature-test macros [allowed] + [[likely]], [[unlikely]] [allowed] + Range-for statements with initializer [allowed] + Three-way comparison (spaceship) operator [allowed] + using enum declarations [allowed] * C++20 Allowed Library Features + [allowed] + [allowed] + [allowed] + Range algorithms [allowed] + Range access, range primitives, dangling iterator handling, and range concepts [allowed] + Library feature-test macros and [allowed] + [allowed] + std::assume_aligned [allowed] + std::erase[_if] for containers [allowed] + std::hardware_{con,de}structive_interference_size [allowed] + std::is_[un]bounded_array [allowed] + std::lerp [allowed] + std::make_obj_using_allocator etc. [allowed] + std::make_unique_for_overwrite [allowed] + std::midpoint [allowed] + std::ranges::subrange [allowed] + std::remove_cvref[_t] [allowed] + std::ssize [allowed] + std::string::(starts,ends)_with [allowed] * C++20 Banned Language Features + char8_t [banned] + Modules [banned] + [[no_unique_address]] [banned] * C++20 Banned Library Features + std::bind_front [banned] + std::bit_cast [banned] + std::{c8rtomb,mbrtoc8} [banned] + Range factories and range adaptors [banned] + std::ranges::view_interface [banned] + [banned] + std::to_address [banned] + [banned] * C++20 TBD Language Features + Aggregate initialization using parentheses [tbd] + Coroutines [tbd] * C++20 TBD Library Features + [tbd] + [tbd] + [tbd] + std::u8string [tbd] * C++23 Allowed Language Features + #elifdef, #elifndef [allowed] + if consteval [allowed] + Static operators () and [] [allowed] * C++23 Allowed Library Features + std::basic_string::contains [allowed] + std::byteswap [allowed] + Various new ranges algorithms [allowed] + std::to_underlying [allowed] * C++23 TBD Language Features + Explicit object parameter [tbd] + Multidimensional subscript operator [tbd] + auto(x), auto{x} [tbd] + [[assume]] [tbd] + #warning [tbd] + Literal suffix for size_t [tbd] + Named character escapes [tbd] * C++23 TBD Library Features + Constructing containers with std::from_range [tbd] + Monadic operations for std::optional [tbd] + std::expected [tbd] + std::flat_map, std::flat_multimap, std::flat_set, std::flat_multiset [tbd] + std::out_ptr, std::inout_ptr [tbd] + std::mdspan [tbd] + std::ranges::to [tbd] + Range Formatting [tbd] + std::print [tbd] + std::generator [tbd] + std::stacktrace [tbd] + std::move_only_function [tbd] + std::unreachable [tbd] + std::spanstream [tbd] + Fixed width floating-point types [tbd] + std::start_lifetime_as [tbd] * Abseil Banned Library Features + Any [banned] + AnyInvocable [banned] + Attributes [banned] + btree_* containers [banned] + bind_front [banned] + Command line flags [banned] + Container utilities [banned] + FixedArray [banned] + FunctionRef [banned] + Log macros and related classes [banned] + NoDestructor [banned] + Nullability annotations [banned] + Optional [banned] + Random [banned] + Span [banned] + StatusOr [banned] + string_view [banned] + Strings Library [banned] + Synchronization [banned] + Time library [banned] + Variant [banned] + Utility library [banned] * Abseil TBD Features + absl::linked_hash_set, absl::linked_hash_map [tbd] C++11 Banned Language Features The following C++11 language features are not allowed in the Chromium codebase. Inline Namespaces [banned] inline namespace foo { ... } Description: Allows better versioning of namespaces. Documentation: Inline namespaces Notes: Banned in the Google Style Guide. Unclear how it will work with components. long long Type [banned] long long var = value; Description: An integer of at least 64 bits. Documentation: Fundamental types Notes: Use a type if you need a 64-bit number. Discussion thread User-Defined Literals [banned] DistanceType var = 12_km; Description: Allows user-defined literal expressions. Documentation: User-defined literals Notes: Banned in the Google Style Guide. C++11 Banned Library Features The following C++11 library features are not allowed in the Chromium codebase. , , , [banned] #include #include #include #include Description: Provides utilities for ASCII characters. Documentation: Standard library header , Standard library header Notes: Banned due to dependence on the C locale as well as UB when arguments don't fit in an unsigned char/wchar_t. Use similarly-named replacements in third_party/abseil-cpp/absl/strings/ascii.h instead. , [banned] #include #include Description: Provides floating point status flags and control modes for C-compatible code. Documentation: Standard library header Notes: Banned by the Google Style Guide due to concerns about compiler support. [banned] #include Description: A standard date and time library. Documentation: Date and time utilities Notes: Overlaps with base/time. [banned] #include Description: Exception throwing and handling. Documentation: Standard library header Notes: Exceptions are banned by the Google Style Guide and disabled in Chromium compiles. However, the noexcept specifier is explicitly allowed. Discussion thread Engines And Generators From [banned] std::mt19937 generator; Description: Methods of generating random numbers. Documentation: Pseudo-random number generation Notes: Do not use any random number engines or generators from . Instead, use base::RandomBitGenerator. (You may use the distributions from .) Discussion thread [banned] #include Description: Provides compile-time rational numbers. Documentation: std::ratio Notes: Banned by the Google Style Guide due to concerns that this is tied to a more template-heavy interface style. [banned] #include Description: A standard regular expressions library. Documentation: Regular expressions library Notes: Overlaps with many regular expression libraries in Chromium. When in doubt, use third_party/re2. std::aligned_{storage,union} [banned] std::aligned_storage>::type buf; Description: Creates aligned, uninitialized storage to later hold one or more objects. Documentation: std::aligned_storage Notes: Deprecated in C++23. Generally, use alignas(T) char buf[sizeof(T)];. Aligned unions can be handled similarly, using the max alignment and size of the union members, either passed via a pack or computed inline. std::bind [banned] auto x = std::bind(function, args, ...); Description: Declares a function object bound to certain arguments. Documentation: std::bind Notes: Use base::Bind instead. Compared to std::bind, base::Bind helps prevent lifetime issues by preventing binding of capturing lambdas and by forcing callers to declare raw pointers as Unretained. Discussion thread std::function [banned] std::function x = [] { return 10; }; std::function y = std::bind(foo, args); Description: Wraps a standard polymorphic function. Documentation: std::function Notes: Use base::{Once,Repeating}Callback or base::FunctionRef instead. Compared to std::function, base::{Once,Repeating}Callback directly supports Chromium's refcounting classes and weak pointers and deals with additional thread safety concerns. Discussion thread std::shared_ptr [banned] std::shared_ptr x = std::make_shared(10); Description: Allows shared ownership of a pointer through reference counts. Documentation: std::shared_ptr Notes: Unlike base::RefCounted, uses extrinsic rather than intrinsic reference counting. Could plausibly be used in Chromium, but would require significant migration. Google Style Guide, Discussion thread std::{sto{i,l,ul,ll,ull,f,d,ld},to_string} [banned] int x = std::stoi("10"); Description: Converts strings to/from numbers. Documentation: std::stoi, std::stol, std::stoll, std::stoul, std::stoull, std::stof, std::stod, std::stold, std::to_string Notes: The string-to-number conversions rely on exceptions to communicate failure, while the number-to-string conversions have performance concerns and depend on the locale. Use base/strings/ string_number_conversions.h instead. std::weak_ptr [banned] std::weak_ptr x = my_shared_x; Description: Allows a weak reference to a std::shared_ptr. Documentation: std::weak_ptr Notes: Banned because std::shared_ptr is banned. Use base::WeakPtr instead. Thread Support Library [banned] #include // C++20 #include #include #include // C++20 #include #include // C++20 #include // C++20 #include Description: Provides a standard multithreading library using std::thread and associates Documentation: Thread support library Notes: Overlaps with base/synchronization. base::Thread is tightly coupled to base::MessageLoop which would make it hard to replace. We should investigate using standard mutexes, or std::unique_lock, etc. to replace our locking/synchronization classes. C++17 Banned Language Features The following C++17 language features are not allowed in the Chromium codebase. UTF-8 character literals [banned] char x = u8'x'; // C++17 char8_t x = u8'x'; // C++20 Description: A character literal that begins with u8 is a character literal of type char (C++17) or char8_t (C++20). The value of a UTF-8 character literal is equal to its ISO 10646 code point value. Documentation: Character literal Notes: Banned because char8_t is banned. Use an unprefixed character or string literal; it should be encoded in the binary as UTF-8 on all supported platforms. C++17 Banned Library Features The following C++17 library features are not allowed in the Chromium codebase. Mathematical special functions [banned] std::assoc_laguerre() std::assoc_legendre() std::beta() std::comp_ellint_1() std::comp_ellint_2() std::comp_ellint_3() std::cyl_bessel_i() std::cyl_bessel_j() std::cyl_bessel_k() std::cyl_neumann() std::ellint_1() std::ellint_2() std::ellint_3() std::expint() std::hermite() std::legendre() std::laguerre() std::riemann_zeta() std::sph_bessel() std::sph_legendre() std::sph_neumann() Description: A variety of mathematical functions. Documentation: Mathematical special functions Notes: Banned due to lack of libc++ support. Parallel algorithms [banned] auto it = std::find(std::execution::par, std::begin(vec), std::end(vec), 2); Description: Many of the STL algorithms, such as the copy, find and sort methods, now support the parallel execution policies: seq, par, and par_unseq which translate to "sequentially", "parallel" and "parallel unsequenced". Documentation: std::execution::sequenced_policy, std::execution::parallel_policy, std::execution::parallel_unsequenced_policy, std::execution::unsequenced_policy Notes: Banned because libc++ support is incomplete and the interaction of its threading implementation with Chrome's is unclear. Prefer to explicitly parallelize long-running algorithms using Chrome's threading APIs, so the same scheduler controls, shutdown policies, tracing, etc. apply as in any other multithreaded code. std::aligned_alloc [banned] int* p2 = static_cast(std::aligned_alloc(1024, 1024)); Description: Allocates uninitialized storage with the specified alignment. Documentation: std::aligned_alloc Notes: Will be allowed soon; for now, use base::AlignedAlloc. std::any [banned] std::any x = 5; Description: A type-safe container for single values of any type. Documentation: std::any Notes: Banned since workaround for lack of RTTI isn't compatible with the component build. See also absl::any. Discussion thread std::byte [banned] std::byte b = 0xFF; int i = std::to_integer(b); // 0xFF Description: The contents of a single memory unit. std::byte has the same size and aliasing rules as unsigned char, but does not semantically represent a character or arithmetic value, and does not expose operators other than bitwise ops. Documentation: std::byte Notes: Banned due to low marginal utility in practice, high conversion costs, and programmer confusion about "byte" vs. "octet". Use uint8_t for the common case of "8-bit unsigned value", and char for the atypical case of code that works with memory without regard to its contents' values or semantics (e.g allocator implementations). Discussion thread std::filesystem [banned] #include Description: A standard way to manipulate files, directories, and paths in a filesystem. Documentation: Filesystem library Notes: Banned by the Google Style Guide. std::{from,to}_chars [banned] std::from_chars(str.data(), str.data() + str.size(), result); std::to_chars(str.data(), str.data() + str.size(), 42); Description: Locale-independent, non-allocating, non-throwing functions to convert values from/to character strings, designed for use in high-throughput contexts. Documentation: std::from_chars std::to_chars, Notes: Overlaps with utilities in base/strings/string_number_conversions.h, which are easier to use correctly. std::{pmr::memory_resource,polymorphic_allocator} [banned] #include Description: Manages memory allocations using runtime polymorphism. Documentation: std::pmr::memory_resource, std::pmr::polymorphic_allocator Notes: Banned because Chromium does not customize allocators (PartitionAlloc is used globally). std::timespec_get [banned] std::timespec ts; std::timespec_get(&ts, TIME_UTC); Description: Gets the current calendar time in the given time base. Documentation: std::timespec_get Notes: Banned due to unclear, implementation-defined behavior. On POSIX, use base::TimeDelta::ToTimeSpec(); this could be supported on other platforms if desirable. std::uncaught_exceptions [banned] int count = std::uncaught_exceptions(); Description: Determines whether there are live exception objects. Documentation: std::uncaught_exceptions Notes: Banned because exceptions are banned. Transparent std::owner_less [banned] std::map, U, std::owner_less<>> Description: Function object providing mixed-type owner-based ordering of shared and weak pointers, regardless of the type of the pointee. Documentation: std::owner_less Notes: Banned since std::shared_ptr and std::weak_ptr are banned. weak_from_this [banned] auto weak_ptr = weak_from_this(); Description: Returns a std::weak_ptr that tracks ownership of *this by all existing std::shared_ptrs that refer to *this. Documentation: std::enable_shared_from_this::weak_from_this Notes: Banned since std::shared_ptr and std::weak_ptr are banned. C++20 Allowed Language Features The following C++20 language features are allowed in the Chromium codebase. Abbreviated function templates [allowed] // template // void f1(T x); void f1(auto x); // template // `C` is a concept // void f2(T x); void f2(C auto x); // template // `C` is a concept // void f3(T x, U y); template void f3(T x, C auto y); // template // void f4(Ts... xs); void f4(auto... xs); Description: Function params of type auto become syntactic sugar for declaring a template type for each such parameter. Documentation: Abbreviated function template Notes: Migration bug consteval [allowed] consteval int sqr(int n) { return n * n; } constexpr int kHundred = sqr(10); // OK constexpr int quad(int n) { return sqr(sqr(n)); } // ERROR, might be runtime Description: Specified that a function may only be used in a compile-time context. Documentation: consteval specifier Notes: None Constraints and concepts [allowed] // `Hashable` is a concept satisfied by any type `T` for which the expression // `std::hash{}(a)` compiles and produces a value convertible to `size_t`. template concept Hashable = requires(T a) { { std::hash{}(a) } -> std::convertible_to; }; template // Only instantiable for `T`s that satisfy `Hashable`. void f(T) { ... } Description: Allows bundling sets of requirements together as named concepts, then enforcing them on template arguments. Documentation: Constraints and concepts Notes: Migration bug Default comparisons [allowed] class S : public T { // Non-member equality operator with access to private members. // Compares `T` bases, then `x`, then `y`, short-circuiting when // it finds inequality. friend bool operator==(const S&, const S&) = default; // Non-member ordering operator with access to private members. // Compares `T` bases, then `x`, then `y`, short-circuiting when // it finds an ordering difference. friend auto operator<=>(const S&, const S&) = default; int x; bool y; }; Description: Requests that the compiler generate the implementation of any comparison operator, including <=>. Prefer non-member comparison operators. When defaulting <=>, also explicitly default = =. Together these are sufficient to allow any comparison as long as callers do not need to take the address of any non-declared operator. Documentation: Default comparisons Notes: Unlike constructors/destructors, our compiler extensions do not require these to be written out-of-line in the .cc file. Feel free to write = default directly in the header, as this is much simpler to write. * Migration bug * Discussion thread Designated initializers [allowed] struct S { int x = 1; int y = 2; } S s{ .y = 3 }; // OK, s.x == 1, s.y == 3 Description: Allows explicit initialization of subsets of aggregate members at construction. Documentation: Designated initializers Notes: None __has_cpp_attribute [allowed] #if __has_cpp_attribute(assume) // Toolchain supports C++23 `[[assume]]`. ... #endif Description: Checks whether the toolchain supports a particular standard attribute. Documentation: Feature testing Notes: None constinit [allowed] constinit int x = 3; void foo() { ++x; } Description: Ensures that a variable can be compile-time initialized. This is like a milder form of constexpr that does not force variables to be const or have constant destruction. Documentation: constinit specifier Notes: Migration bug Initializers for bit-field members [allowed] struct S { uint32_t x : 27 = 2; }; Description: Allows specifying the default initial value of a bit-field member, as can already be done for other member types. Documentation: Bit-field Notes: None Lambda captures with initializers that are pack expansions [allowed] template void foo(Args... args) { const auto l = [...n = args] { (x(n), ...); }; } Description: Allows initializing a capture with a pack expansion. Documentation: Lambda capture Notes: None Language feature-test macros [allowed] #if !defined(__cpp_modules) || (__cpp_modules < 201907L) ... // Toolchain does not support modules #endif Description: Provides a standardized way to test the toolchain's implementation of a particular language feature. Documentation: Feature testing Notes: None [[likely]], [[unlikely]] [allowed] if (n > 0) [[likely]] { return 1; } Description: Tells the optimizer that a particular codepath is more or less likely than an alternative. Documentation: C++ attribute: likely, unlikely Notes: Discussion thread Range-for statements with initializer [allowed] T foo(); ... for (auto& x : foo().items()) { ... } // UAF before C++23! for (T thing = foo(); auto& x : thing.items()) { ... } // OK Description: Like C++17's selection statements with initializer. Particularly useful before C++23, since temporaries inside range-expressions are not lifetime-extended until the end of the loop before C++23. Documentation: Range-based for loop Notes: Migration bug Three-way comparison ("spaceship") operator [allowed] // `ordering` is an instance of `std::strong_odering` or `std::partial_ordering` // that describes how `a` and `b` are related. const auto ordering = a <=> b; if (ordering < 0) { ... } // `a` < `b` else if (ordering > 0) { ... } // `a` > `b` else { ... } // `a` == `b` Description: Compares two objects in a fashion similar to strcmp. Perhaps most useful when defined as an overload in a class, in which case it can replace definitions of other inequalities. See also "Default comparisons". Documentation: Three-way comparison Notes: Migration bug using enum declarations [allowed] enum class E { kA = 1 }; void f() { using enum E; auto a = kA; } Description: Introduces enumerator element names into the current scope. Documentation: using enum declaration Notes: Usage is subject to the Google Style guidelines on aliases. Discussion thread C++20 Allowed Library Features The following C++20 library features are allowed in the Chromium codebase. [allowed] #include Description: Provides various byte- and bit-twiddling functions, e.g. counting leading zeros. Documentation: Standard library header Notes: Migration bug [allowed] #include Description: Concepts and classes used to implement three-way comparison ("spaceship", <=>) support. Documentation: Standard library header Notes: None [allowed] #include Description: Various useful concepts, many of which replace pre-concept machinery in . Documentation: Standard library header Notes: None Range algorithms [allowed] constexpr int kArr[] = {2, 4, 6, 8, 10, 12}; constexpr auto is_even = [] (auto x) { return x % 2 == 0; }; static_assert(std::ranges::all_of(kArr, is_even)); Description: Provides versions of most algorithms that accept either an iterator-sentinel pair or a single range argument. Documentation: Ranges algorithms Notes: Discussion thread Range access, range primitives, dangling iterator handling, and range concepts [allowed] // Range access: constexpr int kArr[] = {2, 4, 6, 8, 10, 12}; static_assert(std::ranges::size(kArr) == 6); // Range primitives: static_assert( std::same_as, const int*>); // Range concepts: static_assert(std::ranges::contiguous_range); Description: Various helper functions and types for working with ranges. Documentation: Ranges library Notes: Supersedes //base's backports in //base//ranges/ranges.h. Discussion thread Library feature-test macros and [allowed] #if !defined(__cpp_lib_atomic_value_initialization) || \ (__cpp_lib_atomic_value_initialization < 201911L) ... // `std::atomic` is not value-initialized by default. #endif Description: Provides a standardized way to test the toolchain's implementation of a particular library feature. Documentation: Feature testing Notes: None [allowed] #include Description: Provides compile-time constants for many common mathematical values, e.g. pi and e. Documentation: Mathematical constants Notes: Migration bug std::assume_aligned [allowed] void f(int* p) { int* aligned = std::assume_aligned<256>(p); ... Description: Informs the compiler that a pointer points to an address aligned to at least some particular power of 2. Documentation: std::assume_aligned Notes: None std::erase[_if] for containers [allowed] std::vector numbers = ...; std::erase_if(numbers, [](int x) { return x % 2 == 0; }); Description: Erases from a container by value comparison or predicate, avoiding the need to use the erase(remove(... paradigm. Documentation: std::erase, std::erase_if (std::vector) Notes: Migration bug std::hardware_{con,de}structive_interference_size [allowed] struct SharedData { ReadOnlyFrequentlyUsed data; alignas(std::hardware_destructive_interference_size) std::atomic counter; }; Description: The std::hardware_destructive_interference_size constant is useful to avoid false sharing (destructive interference) between variables that would otherwise occupy the same cacheline. In contrast, std::hardware_constructive_interference_size is helpful to promote true sharing (constructive interference), e.g. to support better locality for non-contended data. Documentation: std::hardware_destructive_interference_size, std::hardware_constructive_interference_size Notes: Discussion thread std::is_[un]bounded_array [allowed] template static constexpr bool kBoundedArray = std::is_bounded_array_v; Description: Checks if a type is an array type with a known or unknown bound. Documentation: std::is_bounded_array, std::is_unbounded_array Notes: None std::lerp [allowed] double val = std::lerp(start, end, t); Description: Linearly interpolates (or extrapolates) between two values. Documentation: std::lerp Notes: Migration bug std::make_obj_using_allocator etc. [allowed] auto obj = std::make_obj_using_allocator(alloc, ...); Description: Constructs an object using uses-allocator construction. Documentation: std::make_obj_using_allocator Notes: None std::make_unique_for_overwrite [allowed] auto ptr = std::make_unique_for_overwrite(); // `*ptr` is uninitialized Description: Like calling std::unique_ptr(new T) instead of the more typical std::unique_ptr(new T(...)). Documentation: std::make_unique, std::make_unique_for_overwrite Notes: None std::midpoint [allowed] int center = std::midpoint(top, bottom); Description: Finds the midpoint between its two arguments, avoiding any possible overflow. For integral inputs, rounds towards the first argument. Documentation: std::midpoint Notes: Migration bug std::ranges::subrange [allowed] void transform(const std::multimap& map, int key) { auto [first, last] = map.equal_range(key); for (const auto& [_, value] : std::ranges::subrange(first, last)) { ... Description: Creates a view from an iterator and a sentinel. Useful for treating non-contiguous storage (e.g. a std::map) as a range. Documentation: std::ranges::subrange Notes: Prefer base::span if working with explicitly contiguous data, such as in a std::vector. Use std::ranges::subrange when data is non-contiguous, or when it's an implementation detail that the data is contiguous (e.g. base::flat_map). Discussion thread std::remove_cvref[_t] [allowed] template requires (std::is_same_v, int>) void foo(T t); Description: Provides a way to remove const, volatile, and reference qualifiers from a type. Documentation: std::remove_cvref Notes: None std::ssize [allowed] str.replace(it, it + std::ssize(substr), 1, 'x'); Description: Returns the size of an object as a signed type. Documentation: std::size, std::ssize Notes: Migration bug std::string::(starts,ends)_with [allowed] const std::string str = "Foo bar"; const bool is_true = str.ends_with("bar"); Description: Tests whether a string starts or ends with a particular character or string. Documentation: std::basic_string::starts_with , std::basic_string::ends_with Notes: Migration bug C++20 Banned Language Features The following C++20 language features are not allowed in the Chromium codebase. char8_t [banned] char8_t c = u8'x'; Description: A single UTF-8 code unit. Similar to unsigned char, but considered a distinct type. Documentation: Fundamental types Notes: Use char and unprefixed character literals. Non-UTF-8 encodings are rare enough in Chromium that the value of distinguishing them at the type level is low, and char8_t* is not interconvertible with char* (what ~all Chromium, STL, and platform-specific APIs use), so using u8 prefixes would obligate us to insert casts everywhere. If you want to declare at a type level that a block of data is string-like and not an arbitrary binary blob, prefer std::string[_view] over char*. Modules [banned] export module helloworld; // module declaration import ; // import declaration export void hello() { // export declaration std::cout << "Hello world!\n"; } Description: Modules provide an alternative to many uses of headers which allows for faster compilation, better tooling support, and reduction of problems like "include what you use". Documentation: Modules Notes: Not yet sufficiently supported in Clang and GN. Re-evaluate when support improves. [[no_unique_address]] [banned] struct Empty {}; struct X { int i; [[no_unique_address]] Empty e; }; Description: Allows a data member to be overlapped with other members. Documentation: C++ attribute: no_unique_address Notes: Has no effect on Windows, for compatibility with Microsoft's ABI. Use NO_UNIQUE_ADDRESS from base/compiler_specific.h instead. Do not use (either form) on members of unions due to potential memory safety problems. C++20 Banned Library Features The following C++20 library features are not allowed in the Chromium codebase. std::bind_front [banned] int minus(int a, int b); auto fifty_minus_x = std::bind_front(minus, 50); int forty = fifty_minus_x(10); Description: An updated version of std::bind with fewer gotchas, similar to absl::bind_front. Documentation: std::bind_front, std::bind_back Notes: Overlaps with base::Bind. std::bit_cast [banned] float quake_rsqrt(float number) { long i = std::bit_cast(number); i = 0x5f3759df - (i >> 1); // wtf? float y = std::bit_cast(i); return y * (1.5f - (0.5f * number * y * y)); } Description: Returns an value constructed with the same bits as an value of a different type. Documentation: std::bit_cast Notes: The std:: version of bit_cast allows casting of pointer and reference types, which is both useless in that it doesn't avoid UB, and dangerous in that it allows arbitrary casting away of modifiers like const. Instead of using bit_cast on pointers, use standard C++ casts. For use on values, use base::bit_cast which does not allow this unwanted usage. std::{c8rtomb,mbrtoc8} [banned] std::u8string_view strv = u8"zssShui "; std::mbstate_t state; char out[MB_LEN_MAX] = {0}; for (char8_t c : strv) { size_t rc = std::c8rtomb(out, c, &state); ... Description: Converts a code point between UTF-8 and a multibyte character encoded using the current C locale. Documentation: std::c8rtomb, std::mbrtoc8 Notes: Chromium functionality should not vary with the C locale. Range factories and range adaptors [banned] // Prints 1, 2, 3, 4, 5, 6. for (auto i : std::ranges::iota_view(1, 7)) { std::cout << i << '\n'; } constexpr int kArr[] = {6, 2, 8, 4, 4, 2}; constexpr auto plus_one = std::views::transform([](int n){ return n + 1; }); static_assert(std::ranges::equal(kArr | plus_one, {7, 3, 9, 5, 5, 3})); Description: Lightweight objects that represent iterable sequences. Provides facilities for lazy operations on ranges, along with composition into pipelines. Documentation: Ranges library Notes: Banned in Chrome due to questions about the design, impact on build time, and runtime performance. Discussion thread std::ranges::view_interface [banned] class MyView : public std::ranges::view_interface { ... }; Description: CRTP base class for implementing custom view objects. Documentation: std::ranges::view_interface Notes: Banned in Chrome since range factories and adapters are banned, and this would primarily allow authors to create similar functionality. Discussion thread [banned] #include Description: Utilities for non-owning views over a sequence of objects. Documentation: Notes: Superseded by base::span, which has a richer functionality set. std::to_address [banned] std::vector numbers; int* i = std::to_address(numbers.begin()); Description: Converts a pointer-like object to a pointer, even if the pointer does not refer to a constructed object (in which case an expression like &*p is UB). Documentation: std::to_address Notes: Banned because it is not guaranteed to be SFINAE-compatible. Use base::to_address, which does guarantee this. [banned] #include Description: Facilities for multithreaded access to streams. Documentation: Standard library header Notes: Banned due to being unimplemented per the libc++ C++20 status page. Reevaluate usefulness once implemented. C++20 TBD Language Features The following C++20 language features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections. Aggregate initialization using parentheses [tbd] struct B { int a; int&& r; } b2(1, 1); // Warning: dangling reference Description: Allows initialization of aggregates using parentheses, not just braces. Documentation: Aggregate initialization, Direct initialization Notes: There are subtle but important differences between brace- and paren-init of aggregates. The parenthesis style appears to have more pitfalls (allowing narrowing conversions, not extending lifetimes of temporaries bound to references). Coroutines [tbd] co_return 1; Description: Allows writing functions that logically block while physically returning control to a caller. This enables writing some kinds of async code in simple, straight-line ways without storing state in members or binding callbacks. Documentation: Coroutines Notes: Requires significant support code and planning around API and migration. C++20 TBD Library Features The following C++20 library features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections. [tbd] #include Description: Header which defines various core coroutine types. Documentation: Coroutine support Notes: See notes on "Coroutines" above. [tbd] std::cout << std::format("Hello {}!\n", "world"); Description: Utilities for producing formatted strings. Documentation: Formatting library Notes: Has both pros and cons compared to absl::StrFormat (which we don't yet use). Migration would be nontrivial. [tbd] #include Description: Provides a class that can hold source code details such as filenames, function names, and line numbers. Documentation: Standard library header Notes: Seems to regress code size vs. base::Location. std::u8string [tbd] std::u8string str = u8"Foo"; Description: A string whose character type is char8_t, intended to hold UTF-8-encoded text. Documentation: std::basic_string Notes: See notes on char8_t above. C++23 Allowed Language Features The following C++23 language features are allowed in the Chromium codebase. #elifdef, #elifndef [allowed] #ifdef FOO ... #elifdef BAR // New. ... #elifndef BAZ // New. ... #endif Description: New conditional inclusion preprocessor directives. Documentation: Conditional inclusion Notes: Discussion thread if consteval [allowed] if consteval { ... } Description: consteval if statement. This removes some gotchas with std::is_constant_evaluated(), which needs to be used with a runtime if (rather than constexpr if) to be meaningful. Documentation: if statement Notes: Discussion thread Static operators () and [] [allowed] struct FooHash { // Does not take an implicit pointer to `this`, which would have been useless. static size_t operator()(const Foo& foo) { return ...; } }; Description: Static operators () and [] Documentation: Operator overloading Notes: Avoids unnecessary this argument for functors, improving performance. Discussion thread. C++23 Allowed Library Features The following C++23 library features are allowed in the Chromium codebase. std::basic_string::contains [allowed] if (str.contains("foo")) ... Description: More concise substring check. Documentation: std::basic_string::contains Notes: Discussion thread std::byteswap [allowed] auto x = std::byteswap(y); Description: Reverses the bytes of an integer. Documentation: std::byteswap Notes: Discussion thread Various new ranges algorithms [allowed] std::ranges::contains, std::ranges::contains_subrange std::ranges::starts_with std::ranges::ends_with std::ranges::find_last, std::ranges::find_last_if, std::ranges::find_last_if_not std::ranges::iota std::ranges::fold_left std::ranges::fold_left_with_iter // The ones below are pending libc++ implementation as of 01/2026. std::ranges::shift_left, std::ranges::shift_right std::ranges::fold_left_first std::ranges::fold_right std::ranges::fold_right_last std::ranges::fold_left_first_with_iter Description: Various new ranges algorithms Documentation: Notes: Discussion thread. Migration of base::Contains() tracked here. std::to_underlying [allowed] auto x = std::to_underlying(enum_val); Description: Converts an enumeration to its underlying type. Documentation: std::to_underlying Notes: Migration from base::to_underlying is tracked in https://crbug.com/ 470039537. C++23 TBD Language Features The following C++23 language features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections. Explicit object parameter [tbd] struct S { void f(this S& self); }; Description: Allows explicit specification of the object parameter (deducing this) in member functions. Documentation: Explicit object parameter Notes: None Multidimensional subscript operator [tbd] struct S { int operator[](int i, int j); }; Description: Allows multiple arguments in the subscript operator. Documentation: Operator overloading Notes: None auto(x), auto{x} [tbd] void f(const int& i) { auto copy = auto(i); } Description: Prvalue copy (decay-copy). Documentation: Functional cast Notes: None [[assume]] [tbd] [[assume(n > 0)]]; Description: Provides a hint to the optimizer. Documentation: dcl.attr.assume Notes: None #warning [tbd] #warning "This is a warning" Description: Standardized preprocessor warning directive. Documentation: #warning Notes: This was standardized in C++23, but was already supported by clang. From thakis@: #warning doesn't honor -Werror, and we want things to either be errors, or silent. Literal suffix for size_t [tbd] auto s = 10uz; Description: Literal suffix z or uz for std::size_t. Documentation: Integer literal Notes: None Named character escapes [tbd] auto c = "\N{LATIN CAPITAL LETTER A}"; Description: Universal character names using \N{...}. Documentation: Escape sequences Notes: None C++23 TBD Library Features The following C++23 library features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections. Constructing containers with std::from_range [tbd] std::set a_very_long_container_name = {1, 2, 3}; std::vector old_way( a_very_long_container_name.begin(), a_very_long_container_name.end()); std::vector new_way(std::from_range, a_very_long_container_name); Description: More concise conversion from one container type to another. Documentation: std::from_range Notes: See also std::ranges::to which offers something similar. Monadic operations for std::optional [tbd] opt.and_then(f).transform(g).or_else(h); Description: and_then, transform, or_else member functions. Documentation: std::optional Notes: None std::expected [tbd] std::expected e; Description: A vocabulary type that contains an expected value or an error. Documentation: std::expected Notes: Overlaps with base::expected. std::flat_map, std::flat_multimap, std::flat_set, std::flat_multiset [tbd] std::flat_map map; Description: Container adaptors that provide the functionality of associative containers using sorted vectors. Documentation: std::flat_map std::flat_multimap std::flat_set std::flat_multiset Notes: Overlaps with base::flat_map and base::flat_set. std::out_ptr, std::inout_ptr [tbd] std::unique_ptr p; void GetT(T** out); GetT(std::out_ptr(p)); Description: Smart pointer adapters for functions that take raw pointers as out-parameters. Documentation: std::out_ptr, std::inout_ptr Notes: None std::mdspan [tbd] std::mdspan m(ptr, 10, 10); Description: Multidimensional array view. Documentation: std::mdspan Notes: We ban std::span in favor of base::span, which has better safety guarantees. If we want to support this, maybe we should implement base::mdspan. std::ranges::to [tbd] std::set s = {1, 2, 3}; auto u = std::ranges::to(s); auto v = s | std::ranges::to(); Description: Converts a range to a container. Documentation: std::ranges::to Notes: We should ban the 2nd case in the snippet (use as an adaptor), but might want to allow the 1st case (simple container conversion). Note there's also std::from_range for use cases like the 1st one. Range Formatting [tbd] LOG(INFO) << std::format("Values: {}", my_vector); Description: Extends to support printing containers and ranges. Documentation: Notes: As of 01/2026, is still a TBD feature from C++20. std::print [tbd] std::print("Hello {}", "world"); Description: Formatted output. Documentation: Print functions Notes: Overlaps with LOG() and friends. std::generator [tbd] std::generator gen() { co_yield 1; } Description: Coroutine generator. Documentation: std::generator Notes: As of 01/2026, coroutine support in Chromium is still TBD. std::stacktrace [tbd] auto trace = std::stacktrace::current(); Description: Captures a stack trace. Documentation: std::stacktrace Notes: Overlaps with base::debug::StackTrace. std::move_only_function [tbd] std::move_only_function f = [x = std::make_unique(1)] {}; Description: Function wrapper for move-only objects. Documentation: std::move_only_function Notes: Overlaps with base::OnceCallback. std::unreachable [tbd] std::unreachable(); Description: Indicates a codepath that is unreachable and invokes undefined behavior if executed. Documentation: std::unreachable Notes: Standard version of __builtin_unreachable(). Unlike NOTREACHED(), which cleanly aborts, this hints the compiler to optimize assuming this point is unreachable, with no bounds on how the program behaves if the annotation was wrong. This and __builtin_unreachable() should only be used in rare circumstances. std::spanstream [tbd] std::spanstream s(buffer); Description: Input/output stream using a span as buffer. Documentation: std::spanstream Notes: None Fixed width floating-point types [tbd] #include int main() { std::float64_t f = 0.1f64; } Description: Similar to int32_t and friends but for floats. Documentation: Notes: None std::start_lifetime_as [tbd] void* storage = std::malloc(sizeof(T)); T* p = std::start_lifetime_as(storage); Description: Explicitly starts the lifetime of an object of type T in the given storage. Documentation: std::start_lifetime_as Notes: None Abseil Banned Library Features The following Abseil library features are not allowed in the Chromium codebase. Any [banned] absl::any a = int{5}; EXPECT_THAT(absl::any_cast(&a), Pointee(5)); EXPECT_EQ(absl::any_cast(&a), nullptr); Description: Early adaptation of C++17 std::any. Documentation: std::any Notes: Banned since workaround for lack of RTTI isn't compatible with the component build. See also std::any. AnyInvocable [banned] absl::AnyInvocable Description: An equivalent of the C++23 std::move_only_function. Documentation: * any_invocable.h * std::move_only_function Notes: Banned due to overlap with base::RepeatingCallback, base::OnceCallback. Attributes [banned] T* data() ABSL_ATTRIBUTE_LIFETIME_BOUND { return data_; } ABSL_ATTRIBUTE_NO_TAIL_CALL ReturnType Loop(); struct S { bool b; int32_t i; } ABSL_ATTRIBUTE_PACKED; Description: Cross-platform macros to expose compiler-specific functionality. Documentation: attributes.h Notes: Long names discourage use. Use standardized attributes over macros where possible, and otherwise prefer shorter alternatives in base/ compiler_specific.h. Discussion thread btree_* containers [banned] absl::btree_map absl::btree_set absl::btree_multimap absl::btree_multiset Description: Alternatives to the tree-based standard library containers designed to be more efficient in the general case. Documentation: Containers Notes: In theory these should be superior alternatives that could replace most uses of std::map and company. In practice they have been found to introduce a substantial code size increase. Until this problem can be resolved the use of these containers is banned. Use the standard library containers instead. bind_front [banned] absl::bind_front Description: Binds the first N arguments of an invocable object and stores them by value. Documentation: * bind_front.h * Avoid std::bind Notes: Banned due to overlap with base::Bind. Command line flags [banned] ABSL_FLAG(bool, logs, false, "print logs to stderr"); app --logs=true; Description: Allows programmatic access to flag values passed on the command-line to binaries. Documentation: Flags Library Notes: Banned since workaround for lack of RTTI isn't compatible with the component build. Use base::CommandLine instead. Container utilities [banned] auto it = absl::c_find(container, value); Description: Container-based versions of algorithmic functions within C++ standard library. Documentation: container.h Notes: Superseded by algorithms in std::ranges::. FixedArray [banned] absl::FixedArray objs_; Description: A fixed size array like std::array, but with size determined at runtime instead of compile time. Documentation: fixed_array.h Notes: Direct construction is banned due to the risk of UB with uninitialized trivially-default-constructible types. Instead use base /types/fixed_array.h, which is a light-weight wrapper that deletes the problematic constructor. FunctionRef [banned] absl::FunctionRef Description: Type for holding a non-owning reference to an object of any invocable type. Documentation: function_ref.h Notes: * absl::FunctionRef is banned due to allowing implicit conversions between function signatures in potentially surprising ways. For example, a callable with the signature int() will bind to absl::FunctionRef: the return value from the callable will be silently discarded. * In Chromium, use base::FunctionRef instead. * Unlike base::OnceCallback and base::RepeatingCallback, base::FunctionRef supports capturing lambdas. * Useful when passing an invocable object to a function that synchronously calls the invocable object, e.g. ForEachFrame (base::FunctionRef). This can often result in clearer code than code that is templated to accept lambdas, e.g. with template void ForEachFrame(Invocable invocable), it is much less obvious what arguments will be passed to invocable. * For now, base::OnceCallback and base::RepeatingCallback intentionally disallow conversions to base::FunctionRef, under the theory that the callback should be a capturing lambda instead. Attempting to use this conversion will trigger a static_assert requesting additional feedback for use cases where this conversion would be valuable. * Important: base::FunctionRef must not outlive the function call. Like std::string_view, base::FunctionRef is a non-owning reference. Using a base::FunctionRef as a return value or class field is dangerous and likely to result in lifetime bugs. Discussion thread Log macros and related classes [banned] LOG(INFO) << message; CHECK(condition); absl::AddLogSink(&custom_sink_to_capture_absl_logs); Description: Macros and related classes to perform debug loggings Documentation: log.h check.h Notes: Banned due to overlap with base/logging.h. We'd like to drop Chromium's version and replace with the Abseil one, but no one has looked into how to migrate and what impacts (e.g. build time) we'd incur. If you'd like to do this work, please contact cxx@. NoDestructor [banned] // Global or namespace scope. ABSL_CONST_INIT absl::NoDestructor reg{"foo", "bar", 8008}; // Function scope. const std::string& MyString() { static const absl::NoDestructor x("foo"); return *x; } Description: absl::NoDestructor is a wrapper around an object of type T that behaves as an object of type T but never calls T's destructor. Documentation: no_destructor.h Notes: Overlaps with base::NoDestructor. Banned pending rewriting friending of that class into a form usable with this (see crbug.com/392931072); at that point we can allow this and migrate to it. Nullability annotations [banned] void PaySalary(Employee* absl_nonnull employee) { pay(*employee); // OK to dereference } Description: Annotations to more clearly specify contracts Documentation: nullability.h Notes: Banned due to no feasible path to codebase-wide use and little mechanism for enforcement. Optional [banned] absl::optional Func(bool b) { return b ? absl::make_optional(1) : absl::nullopt; } Description: Early adaptation of C++17 std::optional. Documentation: std::optional Notes: Superseded by std::optional. Use std::optional instead. Random [banned] absl::BitGen bitgen; size_t index = absl::Uniform(bitgen, 0u, elems.size()); Description: Functions and utilities for generating pseudorandom data. Documentation: Random library Notes: Banned because most uses of random values in Chromium should be using a cryptographically secure generator. Use base/rand_util.h instead. Span [banned] absl::Span Description: Early adaptation of C++20 std::span. Documentation: Using absl::Span Notes: Banned due to being less std::-compliant than base::span. Keep using base::span. StatusOr [banned] absl::StatusOr Description: An object that is either a usable value, or an error Status explaining why such a value is not present. Documentation: statusor.h Notes: Overlaps with base::expected. string_view [banned] absl::string_view Description: Early adaptation of C++17 std::string_view. Documentation: absl::string_view Notes: Originally banned due to only working with 8-bit characters. Now it is unnecessary because it is the same type as std::string_view. Please use std::string_view instead. Strings Library [banned] absl::StrSplit absl::StrJoin absl::StrCat absl::StrAppend absl::Substitute absl::StrContains Description: Classes and utility functions for manipulating and comparing strings. Documentation: String Utilities Notes: Overlaps with base/strings. We should re-evalute when we've migrated from base::StringPiece to std::string_view. Also note that absl::StrFormat() is not considered part of this group, and is explicitly allowed. Synchronization [banned] absl::Mutex Description: Primitives for managing tasks across different threads. Documentation: Synchronization Notes: Overlaps with base/synchronization/. We would love more testing on whether there are compelling reasons to prefer base, absl, or std synchronization primitives; for now, use base/synchronization/. Time library [banned] absl::Duration absl::Time absl::TimeZone absl::CivilDay Description: Abstractions for holding time values, both in terms of absolute time and civil time. Documentation: Time Notes: Overlaps with base/time/. Variant [banned] absl::bad_variant_access; absl::get; absl::get_if; absl::holds_alternative; absl::monostate; absl::variant; absl::variant_alternative; absl::variant_alternative_t; absl::variant_npos; absl::variant_size; absl::variant_size_v; absl::visit; Description: A backport of C++17's std::variant type-safe union and related utilities. Notes: These are just aliases to the std counterparts these days. Use std instead. Utility library [banned] absl::apply; absl::exchange; absl::forward; absl::in_place; absl::in_place_index; absl::in_place_index_t; absl::in_place_t; absl::in_place_type; absl::in_place_type_t; absl::index_sequence; absl::index_sequence_for; absl::integer_sequence; absl::make_from_tuple; absl::make_index_sequence; absl::make_integer_sequence; absl::move; Description: Backports of various C++17 template utilities. Notes: These are just aliases to the std counterparts these days. Use std instead. Abseil TBD Features The following Abseil library features are not allowed in the Chromium codebase. See the top of this page on how to propose moving a feature from this list into the allowed or banned sections. absl::linked_hash_set, absl::linked_hash_map [tbd] absl::linked_hash_set m; m.insert(2); m.insert(1); m.insert(3); EXPECT_THAT(m, ElementsAre(2, 1, 3)); Description: A simple insertion-ordered set or map. It provides O(1) amortized insertions and lookups, as well as iteration in the insertion order. Documentation: * linked_hash_set.h * linked_hash_map.h Powered by Gitiles| Privacy| Terms sourcelogblame