styleguide/c++/c++-features.md
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 [email protected]. 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:
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:
[TOC]
The following C++11 language features are not allowed in the Chromium codebase.
inline namespace foo { ... }
Description: Allows better versioning of namespaces.
Documentation: Inline namespaces
Notes: *** promo Banned in the Google Style Guide. Unclear how it will work with components.
long long var = value;
Description: An integer of at least 64 bits.
Documentation: Fundamental types
Notes:
*** promo
Use a <stdint.h> type if you need a 64-bit number.
DistanceType var = 12_km;
Description: Allows user-defined literal expressions.
Documentation: User-defined literals
Notes: *** promo Banned in the Google Style Guide.
The following C++11 library features are not allowed in the Chromium codebase.
#include <cctype>
#include <cwctype>
#include <ctype.h>
#include <wctype.h>
Description: Provides utilities for ASCII characters.
Documentation:
Standard library header <cctype>,
Standard library header <cwctype>
Notes:
*** promo
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.
#include <cfenv>
#include <fenv.h>
Description: Provides floating point status flags and control modes for C-compatible code.
Documentation:
Standard library header <cfenv>
Notes: *** promo Banned by the Google Style Guide due to concerns about compiler support.
#include <chrono>
Description: A standard date and time library.
Documentation: Date and time utilities
Notes:
*** promo
Overlaps with base/time.
#include <exception>
Description: Exception throwing and handling.
Documentation:
Standard library header <exception>
Notes:
*** promo
Exceptions are banned by the
Google Style Guide
and disabled in Chromium compiles. However, the noexcept specifier is
explicitly allowed.
std::mt19937 generator;
Description: Methods of generating random numbers.
Documentation: Pseudo-random number generation
Notes:
*** promo
Do not use any random number engines or generators from <random>. Instead, use
base::RandomBitGenerator. (You may use the distributions from <random>.)
#include <ratio>
Description: Provides compile-time rational numbers.
Documentation:
std::ratio
Notes: *** promo Banned by the Google Style Guide due to concerns that this is tied to a more template-heavy interface style.
#include <regex>
Description: A standard regular expressions library.
Documentation: Regular expressions library
Notes:
*** promo
Overlaps with many regular expression libraries in Chromium. When in doubt, use
third_party/re2.
std::aligned_storage<sizeof(T), alignof<T>>::type buf;
Description: Creates aligned, uninitialized storage to later hold one or more objects.
Documentation:
std::aligned_storage
Notes:
*** promo
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.
auto x = std::bind(function, args, ...);
Description: Declares a function object bound to certain arguments.
Documentation:
std::bind
Notes:
*** promo
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.
std::function x = [] { return 10; };
std::function y = std::bind(foo, args);
Description: Wraps a standard polymorphic function.
Documentation:
std::function
Notes:
*** promo
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.
std::shared_ptr<int> x = std::make_shared<int>(10);
Description: Allows shared ownership of a pointer through reference counts.
Documentation:
std::shared_ptr
Notes:
*** promo
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
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:
*** promo
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<int> x = my_shared_x;
Description: Allows a weak reference to a std::shared_ptr.
Documentation:
std::weak_ptr
Notes:
*** promo
Banned because std::shared_ptr is banned. Use base::WeakPtr instead.
#include <barrier> // C++20
#include <condition_variable>
#include <future>
#include <latch> // C++20
#include <mutex>
#include <semaphore> // C++20
#include <stop_token> // C++20
#include <thread>
Description: Provides a standard multithreading library using std::thread
and associates
Documentation: Thread support library
Notes:
*** promo
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.
The following C++17 language features are not allowed in the Chromium codebase.
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:
*** promo
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.
The following C++17 library features are not allowed in the Chromium codebase.
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: *** promo Banned due to lack of libc++ support.
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".
Notes: *** promo 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.
int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
Description: Allocates uninitialized storage with the specified alignment.
Documentation:
std::aligned_alloc
Notes:
*** promo
Will be allowed soon; for now, use
base::AlignedAlloc.
std::any x = 5;
Description: A type-safe container for single values of any type.
Documentation:
std::any
Notes:
*** promo
Banned since workaround for lack of RTTI
isn't compatible with the component build. See also
absl::any.
std::byte b = 0xFF;
int i = std::to_integer<int>(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:
*** promo
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).
#include <filesystem>
Description: A standard way to manipulate files, directories, and paths in a filesystem.
Documentation: Filesystem library
Notes: *** promo Banned by the Google Style Guide.
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:
*** promo
Overlaps with utilities in base/strings/string_number_conversions.h, which are
easier to use correctly.
#include <memory_resource>
Description: Manages memory allocations using runtime polymorphism.
Documentation:
std::pmr::memory_resource,
std::pmr::polymorphic_allocator
Notes: *** promo Banned because Chromium does not customize allocators (PartitionAlloc is used globally).
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:
*** promo
Banned due to unclear, implementation-defined behavior. On POSIX, use
base::TimeDelta::ToTimeSpec(); this could be supported on other platforms if
desirable.
int count = std::uncaught_exceptions();
Description: Determines whether there are live exception objects.
Documentation:
std::uncaught_exceptions
Notes: *** promo Banned because exceptions are banned.
std::map<std::weak_ptr<T>, 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:
*** promo
Banned since std::shared_ptr and std::weak_ptr are banned.
auto weak_ptr = weak_from_this();
Description: Returns a std::weak_ptr<T> that tracks ownership of *this
by all existing std::shared_ptrs that refer to *this.
Documentation:
std::enable_shared_from_this<T>::weak_from_this
Notes:
*** promo
Banned since std::shared_ptr and std::weak_ptr are banned.
The following C++20 language features are allowed in the Chromium codebase.
// template <typename T>
// void f1(T x);
void f1(auto x);
// template <C T> // `C` is a concept
// void f2(T x);
void f2(C auto x);
// template <typename T, C U> // `C` is a concept
// void f3(T x, U y);
template <typename T>
void f3(T x, C auto y);
// template<typename... Ts>
// 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: *** promo Migration bug
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: *** promo There are subtle but important differences between brace-init and paren-init of aggregates. The parenthesis style has some pitfalls, e.g. allowing narrowing conversions and not extending lifetimes of temporaries bound to references, but this matches the behavior of paren-init of non-aggregate types which is already 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: *** promo None
// `Hashable` is a concept satisfied by any type `T` for which the expression
// `std::hash<T>{}(a)` compiles and produces a value convertible to `size_t`.
template<typename T>
concept Hashable = requires(T a)
{
{ std::hash<T>{}(a) } -> std::convertible_to<size_t>;
};
template <Hashable T> // 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: *** promo Migration bug
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:
*** promo
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.
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: *** promo None
#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: *** promo None
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: *** promo Migration bug
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: *** promo None
template <typename... Args>
void foo(Args... args) {
const auto l = [...n = args] { (x(n), ...); };
}
Description: Allows initializing a capture with a pack expansion.
Documentation: Lambda capture
Notes: *** promo None
#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: *** promo None
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: *** promo Discussion thread
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: *** promo Migration bug
// `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: *** promo Migration bug
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: *** promo Usage is subject to the Google Style guidelines on aliases.
The following C++20 library features are allowed in the Chromium codebase.
#include <bit>
Description: Provides various byte- and bit-twiddling functions, e.g. counting leading zeros.
Documentation:
Standard library header <bit>
Notes: *** promo Migration bug
#include <compare>
Description: Concepts and classes used to implement three-way comparison
("spaceship", <=>) support.
Documentation:
Standard library header <compare>
Notes: *** promo None
#include <concepts>
Description: Various useful concepts, many of which replace pre-concept
machinery in <type_traits>.
Documentation:
Standard library header <concepts>
Notes: *** promo None
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: *** promo Discussion thread
// 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<std::ranges::iterator_t<decltype(kArr)>, const int*>);
// Range concepts:
static_assert(std::ranges::contiguous_range<decltype(kArr)>);
Description: Various helper functions and types for working with ranges.
Documentation: Ranges library
Notes:
*** promo
Supersedes //base's backports in //base//ranges/ranges.h.
#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: *** promo None
#include <numbers>
Description: Provides compile-time constants for many common mathematical values, e.g. pi and e.
Documentation: Mathematical constants
Notes: *** promo Migration bug
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: *** promo None
std::vector<int> 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: *** promo Migration bug
struct SharedData {
ReadOnlyFrequentlyUsed data;
alignas(std::hardware_destructive_interference_size) std::atomic<size_t> 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: *** promo Discussion thread
template <typename T>
static constexpr bool kBoundedArray = std::is_bounded_array_v<T>;
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: *** promo None
double val = std::lerp(start, end, t);
Description: Linearly interpolates (or extrapolates) between two values.
Documentation:
std::lerp
Notes: *** promo Migration bug
auto obj = std::make_obj_using_allocator<Obj>(alloc, ...);
Description: Constructs an object using uses-allocator construction.
Documentation:
std::make_obj_using_allocator
Notes: *** promo None
auto ptr = std::make_unique_for_overwrite<int>(); // `*ptr` is uninitialized
Description: Like calling std::unique_ptr<T>(new T) instead of the more
typical std::unique_ptr<T>(new T(...)).
Documentation:
std::make_unique, std::make_unique_for_overwrite
Notes: *** promo None
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: *** promo Migration bug
void transform(const std::multimap<int, char>& 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:
*** promo
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).
template <typename T>
requires (std::is_same_v<std::remove_cvref_t<T>, int>)
void foo(T t);
Description: Provides a way to remove const, volatile, and reference qualifiers from a type.
Documentation:
std::remove_cvref
Notes: *** promo None
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: *** promo Migration bug
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<CharT,Traits,Allocator>::starts_with,
std::basic_string<CharT,Traits,Allocator>::ends_with
Notes: *** promo Migration bug
The following C++20 language features are not allowed in the Chromium codebase.
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:
*** promo
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*.
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: *** promo Requires significant support code and planning around API and migration, see discussion thread. Re-evaluate once supported on win32 and there is a plan for how to integrate with Chrome task scheduling.
export module helloworld; // module declaration
import <iostream>; // 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: *** promo Not yet sufficiently supported in Clang and GN. Re-evaluate when support improves.
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:
*** promo
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.
The following C++20 library features are not allowed in the Chromium codebase.
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:
*** promo
Overlaps with base::Bind.
float quake_rsqrt(float number) {
long i = std::bit_cast<long>(number);
i = 0x5f3759df - (i >> 1); // wtf?
float y = std::bit_cast<float>(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:
*** promo
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::u8string_view strv = u8"zß水🍌";
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: *** promo Chromium functionality should not vary with the C locale.
#include <coroutine>
Description: Header which defines various core coroutine types.
Documentation: Coroutine support
Notes: *** promo See notes on "Coroutines" above.
std::cout << std::format("Hello {}!\n", "world");
Description: Utilities for producing formatted strings.
Documentation: Formatting library
Notes:
*** promo
Has both pros and cons compared to absl::StrFormat (which we use internally in
base::StringPrintf). Migration would be nontrivial due to string format
specifiers being different. The external {fmt} library might be a better
candidate to switch to.
// 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: *** promo Banned in Chrome due to questions about the design, impact on build time, and runtime performance.
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: The pipe operator for chaining range adaptor closure objects.
Documentation:
std::ranges::operator|
Notes: *** promo Banned in Chromium since range factories and adapters are banned. Explicitly enforced by the Chromium style clang-plugin.
class MyView : public std::ranges::view_interface<MyView> { ... };
Description: CRTP base class for implementing custom view objects.
Documentation:
std::ranges::view_interface
Notes: *** promo Banned in Chrome since range factories and adapters are banned, and this would primarily allow authors to create similar functionality.
#include <source_location>
Description: Provides a class that can hold source code details such as filenames, function names, and line numbers.
Documentation:
Standard library header <source_location>
Notes:
*** promo
Regresses binary size vs. base::Location, see
discussion here.
#include <span>
Description: Utilities for non-owning views over a sequence of objects.
Notes:
*** promo
Superseded by base::span, which has a richer functionality set.
std::vector<int> 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: *** promo Banned because it is not guaranteed to be SFINAE-compatible. Use base::to_address, which does guarantee this.
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:
*** promo
See notes on char8_t above.
#include <syncstream>
Description: Facilities for multithreaded access to streams.
Documentation:
Standard library header <syncstream>
Notes: *** promo Banned due to being unimplemented per the libc++ C++20 status page. Reevaluate usefulness once implemented.
The following C++23 language features are allowed in the Chromium codebase.
#ifdef FOO
...
#elifdef BAR // New.
...
#elifndef BAZ // New.
...
#endif
Description: New conditional inclusion preprocessor directives.
Documentation: Conditional inclusion
Notes: *** promo Discussion thread
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: *** promo Discussion thread
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:
*** promo
Avoids unnecessary this argument for functors, improving performance.
Discussion thread.
The following C++23 library features are allowed in the Chromium codebase.
if (str.contains("foo")) ...
Description: More concise substring check.
Documentation: std::basic_string::contains
Notes: *** promo Discussion thread
auto x = std::byteswap(y);
Description: Reverses the bytes of an integer.
Documentation: std::byteswap
Notes: *** promo Discussion thread
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:
<algorithm>
Notes: *** promo Discussion thread. Migration of base::Contains() tracked here.
std::set<int> a_very_long_container_name = {1, 2, 3};
std::vector<int> old_way(
a_very_long_container_name.begin(), a_very_long_container_name.end());
std::vector<int> 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: *** promo Discussion thread. See also std::ranges::to which offers something similar.
std::set<int> s = {1, 2, 3};
auto u = std::ranges::to<std::vector>(s);
Description: Converts a range to a container.
Documentation: std::ranges::to
Notes:
*** promo
Discussion thread.
NOTE: std::ranges::to could also be used as a range adaptor, but those are
banned in Chromium, see here.
auto x = std::to_underlying(enum_val);
Description: Converts an enumeration to its underlying type.
Documentation: std::to_underlying
Notes:
*** promo
Migration from base::to_underlying is tracked in https://crbug.com/470039537.
opt.and_then(f).transform(g).or_else(h);
Description: and_then, transform, or_else member functions.
Documentation: std::optional
Notes: *** promo Discussion thread.
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.
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: *** promo None
struct S {
int operator[](int i, int j);
};
Description: Allows multiple arguments in the subscript operator.
Documentation: Operator overloading
Notes: *** promo None
void f(const int& i) {
auto copy = auto(i);
}
Description: Prvalue copy (decay-copy).
Documentation: Functional cast
Notes: *** promo None
[[assume(n > 0)]];
Description: Provides a hint to the optimizer.
Documentation: dcl.attr.assume
Notes: *** promo None
#warning "This is a warning"
Description: Standardized preprocessor warning directive.
Documentation: #warning
Notes: *** promo 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.
auto s = 10uz;
Description: Literal suffix z or uz for std::size_t.
Documentation: Integer literal
Notes: *** promo None
auto c = "\N{LATIN CAPITAL LETTER A}";
Description: Universal character names using \N{...}.
Documentation: Escape sequences
Notes: *** promo None
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.
std::expected<int, std::string> e;
Description: A vocabulary type that contains an expected value or an error.
Documentation: std::expected
Notes:
*** promo
Overlaps with base::expected.
std::flat_map<int, std::string> 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:
*** promo
Overlaps with base::flat_map and base::flat_set.
std::unique_ptr<T> 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: *** promo None
std::mdspan m(ptr, 10, 10);
Description: Multidimensional array view.
Documentation: std::mdspan
Notes: *** promo 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.
LOG(INFO) << std::format("Values: {}", my_vector);
Description: Extends <format> to support printing containers and ranges.
Documentation:
<format>
Notes:
*** promo
As of 01/2026, <format> is still a TBD feature from C++20.
std::print("Hello {}", "world");
Description: Formatted output.
Documentation: Print functions
Notes: *** promo Overlaps with LOG() and friends.
std::generator<int> gen() { co_yield 1; }
Description: Coroutine generator.
Documentation: std::generator
Notes: *** promo As of 01/2026, coroutine support in Chromium is still TBD.
auto trace = std::stacktrace::current();
Description: Captures a stack trace.
Documentation: std::stacktrace
Notes:
*** promo
Overlaps with base::debug::StackTrace.
std::move_only_function<void()> f = [x = std::make_unique<int>(1)] {};
Description: Function wrapper for move-only objects.
Documentation: std::move_only_function
Notes:
*** promo
Overlaps with base::OnceCallback.
std::unreachable();
Description: Indicates a codepath that is unreachable and invokes undefined behavior if executed.
Documentation: std::unreachable
Notes:
*** promo
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 s(buffer);
Description: Input/output stream using a span as buffer.
Documentation: std::spanstream
Notes: *** promo None
#include <stdfloat>
int main()
{
std::float64_t f = 0.1f64;
}
Description: Similar to int32_t and friends but for floats.
Documentation: <stdfloat>
Notes: *** promo None
void* storage = std::malloc(sizeof(T));
T* p = std::start_lifetime_as<T>(storage);
Description: Explicitly starts the lifetime of an object of type T in the given storage.
Documentation: std::start_lifetime_as
Notes: *** promo None
The following Abseil library features are not allowed in the Chromium codebase.
absl::any a = int{5};
EXPECT_THAT(absl::any_cast<int>(&a), Pointee(5));
EXPECT_EQ(absl::any_cast<size_t>(&a), nullptr);
Description: Early adaptation of C++17 std::any.
Documentation: std::any
Notes:
*** promo
Banned since workaround for lack of RTTI
isn't compatible with the component build. See also
std::any.
absl::AnyInvocable
Description: An equivalent of the C++23 std::move_only_function.
Documentation:
Notes:
*** promo
Banned due to overlap with base::RepeatingCallback, base::OnceCallback.
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:
*** promo
Long names discourage use. Use standardized attributes over macros where
possible, and otherwise prefer shorter alternatives in
base/compiler_specific.h.
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:
*** promo
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.
absl::bind_front
Description: Binds the first N arguments of an invocable object and stores them by value.
Documentation:
Notes:
*** promo
Banned due to overlap with base::Bind.
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:
*** promo
Banned since workaround for lack of RTTI
isn't compatible with the component build. Use
base::CommandLine instead.
auto it = absl::c_find(container, value);
Description: Container-based versions of algorithmic functions within C++ standard library.
Documentation: container.h
Notes:
*** promo
Superseded by algorithms in std::ranges::.
absl::FixedArray<MyObj> objs_;
Description: A fixed size array like std::array, but with size determined
at runtime instead of compile time.
Documentation: fixed_array.h
Notes:
*** promo
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.
absl::FunctionRef
Description: Type for holding a non-owning reference to an object of any invocable type.
Documentation: function_ref.h
Notes: *** promo
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<void()>: the
return value from the callable will be silently discarded.base::FunctionRef instead.base::OnceCallback and base::RepeatingCallback, base::FunctionRef
supports capturing lambdas.ForEachFrame(base::FunctionRef<void(Frame&)>).
This can often result in clearer code than code that is templated to accept
lambdas, e.g. with template <typename Invocable> void ForEachFrame(Invocable invocable), it is much less obvious what arguments
will be passed to invocable.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.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.LOG(INFO) << message;
CHECK(condition);
absl::AddLogSink(&custom_sink_to_capture_absl_logs);
Description: Macros and related classes to perform debug loggings
Notes:
*** promo
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@.
// Global or namespace scope.
ABSL_CONST_INIT absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
// Function scope.
const std::string& MyString() {
static const absl::NoDestructor<std::string> x("foo");
return *x;
}
Description: absl::NoDestructor<T> 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:
*** promo
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.
void PaySalary(Employee* absl_nonnull employee) {
pay(*employee); // OK to dereference
}
Description: Annotations to more clearly specify contracts
Documentation: nullability.h
Notes: *** promo Banned due to no feasible path to codebase-wide use and little mechanism for enforcement.
absl::optional<int> Func(bool b) {
return b ? absl::make_optional(1) : absl::nullopt;
}
Description: Early adaptation of C++17 std::optional.
Documentation: std::optional
Notes:
*** promo
Superseded by std::optional. Use std::optional instead.
absl::BitGen bitgen;
size_t index = absl::Uniform(bitgen, 0u, elems.size());
Description: Functions and utilities for generating pseudorandom data.
Documentation: Random library
Notes:
*** promo
Banned because most uses of random values in Chromium should be using a
cryptographically secure generator. Use base/rand_util.h instead.
absl::Span
Description: Early adaptation of C++20 std::span.
Documentation: Using absl::Span
Notes:
*** promo
Banned due to being less std::-compliant than base::span. Keep using
base::span.
absl::StatusOr<T>
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:
*** promo
Overlaps with base::expected.
absl::string_view
Description: Early adaptation of C++17 std::string_view.
Documentation: absl::string_view
Notes:
*** promo
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.
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:
*** promo
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.
absl::Mutex
Description: Primitives for managing tasks across different threads.
Documentation: Synchronization
Notes:
*** promo
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/.
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:
*** promo
Overlaps with base/time/.
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: *** promo These are just aliases to the std counterparts these days. Use std instead.
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: *** promo These are just aliases to the std counterparts these days. Use std instead.
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.
void MyFunction(AnySpan<const MyMessage> messages);
// Invoke with container of smart pointers.
std::deque<std::unique_ptr<MyMessage>> message_ptrs = ...;
MyFunction(AnySpan<const MyMessage>(message_ptrs, any_span_transform::Deref()));
// Invoke with a repeated proto field of type MyMessage.
OtherMessage proto_message = ...;
MyFunction(proto_message.repeated_field());
Description: Provides a view of a random access container, much like absl::Span, except it can handle more container types and perform a variety of useful transformations.
Documentation:
absl::linked_hash_set<int> 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:
void ProcessT(absl::optional_ref<const T> input) {
if (!input.has_value()) {
// Handle empty case.
return;
}
const T& val = *input;
// Do something with val.
}
ProcessT(std::nullopt);
ProcessT(BuildT());
Description: A std::optional-like interface around T*.
It is similar to C++26's std::optional<T&>, but with slight enhancements.
Documentation:
void TracedAdd(int i, SourceLocation loc = SourceLocation::current()) {
std::cout << loc.file_name() << ":" << loc.line() << " added " << i;
...
}
void UserCode() {
TracedAdd(1);
TracedAdd(2);
}
Description: provides source-code location info.
It is similar to C++20's std::source_location. Unlike std::source_location,
it is not permanently valid and must not outlive its source.
Documentation:
Notes:
*** promo
Overlaps with base::Location.