| # Modern C++ use in Chromium |
| |
| _This document is part of the more general |
| [Chromium C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md). |
| It summarizes the supported state of new and updated language and library |
| features in recent C++ standards and the [Abseil](https://abseil.io/about/) |
| 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, C++17). For various reasons, Chromium does not immediately |
| allow new features on the publication of such a standard. Instead, once |
| toolchain support is sufficient, a standard is declared "initially supported", |
| with new language/library features banned pending discussion. |
| |
| You can propose changing the status of a feature by sending an email to |
| [cxx@chromium.org](https://groups.google.com/a/chromium.org/forum/#!forum/cxx). |
| 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; see banned features below_ |
| * **C++17:** _Not yet supported in Chromium, unlikely before mid-2021; |
| [tracking bug](https://crbug.com/752720)_ |
| * **C++20:** _Not yet standardized_ |
| * **Abseil:** Initially supported July 31, 2020; see allowed/banned/TBD |
| features below |
| * absl::StatusOr: Initially supported September 3, 2020 |
| * absl::Cleanup: Initially supported February 4, 2021 |
| |
| [TOC] |
| |
| ## C++11 Banned Language Features {#core-blocklist} |
| |
| The following C++11 language features are not allowed in the Chromium codebase. |
| |
| ### Inline Namespaces |
| |
| ```c++ |
| inline namespace foo { ... } |
| ``` |
| |
| **Description:** Allows better versioning of namespaces. |
| |
| **Documentation:** |
| [Inline namespaces](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) |
| |
| **Notes:** |
| *** promo |
| Banned in the |
| [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Namespaces). |
| Unclear how it will work with components. |
| *** |
| |
| ### long long Type |
| |
| ```c++ |
| long long var = value; |
| ``` |
| |
| **Description:** An integer of at least 64 bits. |
| |
| **Documentation:** |
| [Fundamental types](https://en.cppreference.com/w/cpp/language/types) |
| |
| **Notes:** |
| *** promo |
| Use a stdint.h type if you need a 64-bit number. |
| [Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/RxugZ-pIDxk) |
| *** |
| |
| ### User-Defined Literals |
| |
| ```c++ |
| type var = literal_value_type; |
| ``` |
| |
| **Description:** Allows user-defined literal expressions. |
| |
| **Documentation:** |
| [User-defined literals](https://en.cppreference.com/w/cpp/language/user_literal) |
| |
| **Notes:** |
| *** promo |
| Banned in the |
| [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading). |
| *** |
| |
| ### thread_local Storage Class |
| |
| ```c++ |
| thread_local int foo = 1; |
| ``` |
| |
| **Description:** Puts variables into thread local storage. |
| |
| **Documentation:** |
| [Storage duration](https://en.cppreference.com/w/cpp/language/storage_duration) |
| |
| **Notes:** |
| *** promo |
| Some surprising effects on Mac |
| ([discussion](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs), |
| [fork](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw)). |
| Use `base::SequenceLocalStorageSlot` for sequence support, and |
| `base::ThreadLocal`/`base::ThreadLocalStorage` otherwise. |
| *** |
| |
| ## C++11 Banned Library Features {#library-blocklist} |
| |
| The following C++11 library features are not allowed in the Chromium codebase. |
| |
| ### Bind Operations |
| |
| ```c++ |
| std::bind(function, args, ...) |
| ``` |
| |
| **Description:** Declares a function object bound to certain arguments |
| |
| **Documentation:** |
| [std::bind](https://en.cppreference.com/w/cpp/utility/functional/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`. |
| [Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA) |
| *** |
| |
| ### C Floating-Point Environment |
| |
| ```c++ |
| #include <cfenv> |
| #include <fenv.h> |
| ``` |
| |
| **Description:** Provides floating point status flags and control modes for |
| C-compatible code |
| |
| **Documentation:** |
| [Standard library header "cfenv"](https://en.cppreference.com/w/cpp/header/cfenv) |
| |
| **Notes:** |
| *** promo |
| Banned by the |
| [Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11) |
| due to concerns about compiler support. |
| *** |
| |
| ### Date and time utilities |
| |
| ```c++ |
| #include <chrono> |
| ``` |
| |
| **Description:** A standard date and time library |
| |
| **Documentation:** |
| [Date and time utilities](https://en.cppreference.com/w/cpp/chrono) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `Time` APIs in `base/`. Keep using the `base/` classes. |
| *** |
| |
| ### Exceptions |
| |
| ```c++ |
| #include <exception> |
| ``` |
| |
| **Description:** Enhancements to exception throwing and handling |
| |
| **Documentation:** |
| [Standard library header "exception"](https://en.cppreference.com/w/cpp/header/exception) |
| |
| **Notes:** |
| *** promo |
| Exceptions are banned by the |
| [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Exceptions) |
| and disabled in Chromium compiles. However, the `noexcept` specifier is |
| explicitly allowed. |
| [Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8i4tMqNpHhg) |
| *** |
| |
| ### Function Objects |
| |
| ```c++ |
| std::function |
| ``` |
| |
| **Description:** Wraps a standard polymorphic function |
| |
| **Documentation:** |
| [std::function](https://en.cppreference.com/w/cpp/utility/functional/function) |
| |
| **Notes:** |
| *** promo |
| Use `base::{Once,Repeating}Callback` 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](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/SoEj7oIDNuA) |
| *** |
| |
| ### Random Number Engines |
| |
| *** aside |
| The random number engines defined in `<random>` (see separate item for random |
| number distributions), e.g.: `linear_congruential_engine`, |
| `mersenne_twister_engine`, `minstd_rand0`, `mt19937`, `ranlinux48`, |
| `random_device` |
| *** |
| |
| **Description:** Random number generation algorithms and utilities. |
| |
| **Documentation:** |
| [Pseudo-random number generation](https://en.cppreference.com/w/cpp/numeric/random) |
| |
| **Notes:** |
| *** promo |
| Do not use any random number engines from `<random>`. Instead, use |
| `base::RandomBitGenerator`. |
| [Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/16Xmw05C-Y0) |
| *** |
| |
| ### Ratio Template Class |
| |
| ```c++ |
| std::ratio<numerator, denominator> |
| ``` |
| |
| **Description:** Provides compile-time rational numbers |
| |
| **Documentation:** |
| [std::ratio](https://en.cppreference.com/w/cpp/numeric/ratio/ratio) |
| |
| **Notes:** |
| *** promo |
| Banned by the |
| [Google Style Guide](https://google.github.io/styleguide/cppguide.html#C++11) |
| due to concerns that this is tied to a more template-heavy interface style. |
| *** |
| |
| ### Regular Expressions |
| |
| ```c++ |
| #include <regex> |
| ``` |
| |
| **Description:** A standard regular expressions library |
| |
| **Documentation:** |
| [Regular expressions library](https://en.cppreference.com/w/cpp/regex) |
| |
| **Notes:** |
| *** promo |
| Overlaps with many regular expression libraries in Chromium. When in doubt, use |
| `re2`. |
| *** |
| |
| ### Shared Pointers |
| |
| ```c++ |
| std::shared_ptr |
| ``` |
| |
| **Description:** Allows shared ownership of a pointer through reference counts |
| |
| **Documentation:** |
| [std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr) |
| |
| **Notes:** |
| *** promo |
| Needs a lot more evaluation for Chromium, and there isn't enough of a push for |
| this feature. |
| |
| * [Google Style Guide](https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers). |
| * [Discussion Thread](https://groups.google.com/a/chromium.org/forum/#!topic/cxx/aT2wsBLKvzI) |
| *** |
| |
| ### String-Number Conversion Functions |
| |
| ```c++ |
| std::stoi() |
| std::stol() |
| std::stoul() |
| std::stoll |
| std::stoull() |
| std::stof() |
| std::stod() |
| std::stold() |
| std::to_string() |
| ``` |
| |
| **Description:** Converts strings to/from numbers |
| |
| **Documentation:** |
| * [std::stoi, std::stol, std::stoll](https://en.cppreference.com/w/cpp/string/basic_string/stol), |
| * [std::stoul, std::stoull](https://en.cppreference.com/w/cpp/string/basic_string/stoul), |
| * [std::stof, std::stod, std::stold](https://en.cppreference.com/w/cpp/string/basic_string/stof), |
| * [std::to_string](https://en.cppreference.com/w/cpp/string/basic_string/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 the routines in `base/strings/string_number_conversions.h` |
| instead. |
| *** |
| |
| ### Thread Library |
| |
| *** aside |
| `<thread>` and related headers, including `<future>`, `<mutex>`, |
| `<condition_variable>` |
| *** |
| |
| **Description:** Provides a standard multithreading library using `std::thread` |
| and associates |
| |
| **Documentation:** |
| [Thread support library](https://en.cppreference.com/w/cpp/thread) |
| |
| **Notes:** |
| *** promo |
| Overlaps with many classes in `base/`. Keep using the `base/` classes for now. |
| `base::Thread` is tightly coupled to `MessageLoop` which would make it hard to |
| replace. We should investigate using standard mutexes, or unique_lock, etc. to |
| replace our locking/synchronization classes. |
| *** |
| |
| ### Weak Pointers |
| |
| ```c++ |
| std::weak_ptr |
| ``` |
| |
| **Description:** Allows a weak reference to a `std::shared_ptr` |
| |
| **Documentation:** |
| [std::weak_ptr](https://en.cppreference.com/w/cpp/memory/weak_ptr) |
| |
| **Notes:** |
| *** promo |
| Banned because `std::shared_ptr` is banned. Use `base::WeakPtr` instead. |
| *** |
| |
| ## C++14 Banned Library Features {#library-blocklist-14} |
| |
| The following C++14 library features are not allowed in the Chromium codebase. |
| |
| ### std::chrono literals |
| |
| ```c++ |
| using namespace std::chrono_literals; |
| auto timeout = 30s; |
| ``` |
| |
| **Description:** Allows `std::chrono` types to be more easily constructed. |
| |
| **Documentation:** |
| [std::literals::chrono_literals::operator""s](https://en.cppreference.com/w/cpp/chrono/operator%22%22s) |
| |
| **Notes:** |
| *** promo |
| Banned because `<chrono>` is banned. |
| *** |
| |
| ## Abseil Allowed Library Features {#absl-allowlist} |
| |
| The following Abseil library features are allowed in the Chromium codebase. |
| |
| ### Optional |
| |
| ```c++ |
| absl::optional |
| ``` |
| |
| **Description:** Early adaptation of C++17 `std::optional`. |
| |
| **Documentation:** |
| [std::optional](https://en.cppreference.com/w/cpp/utility/optional) |
| |
| **Notes:** |
| *** promo |
| Replaces `base::Optional`. |
| [Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/zUGqagX1NFU) |
| *** |
| |
| ### Status |
| |
| ```c++ |
| absl::Status |
| ``` |
| |
| **Description:** Type for returning detailed errors. |
| |
| **Documentation:** |
| [status.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/status.h) |
| |
| **Notes:** |
| *** promo |
| Approved for use inside a wrapper type. Use |
| [abseil_string_conversions.h](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/abseil_string_conversions.h) |
| to convert to and from |
| [absl::string_view](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/string_view.h) |
| so the wrapper can expose |
| [base::StringPiece](https://source.chromium.org/chromium/chromium/src/+/main:base/strings/string_piece.h). |
| Use |
| [absl::Cord](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/strings/cord.h) |
| directly as minimally necessary to interface; do not expose in the wrapper type |
| API. |
| |
| [Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ImdFCSZ-NMA) |
| *** |
| |
| ### Variant |
| |
| ```c++ |
| absl::variant |
| ``` |
| |
| **Description:** Early adaptation of C++17 `std::variant`. |
| |
| **Documentation:** |
| [std::variant](https://en.cppreference.com/w/cpp/utility/variant) |
| |
| **Notes:** |
| *** promo |
| [Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/DqvG-TpvMyU) |
| *** |
| |
| ## Abseil Banned Library Features {#absl-blocklist} |
| |
| The following Abseil library features are not allowed in the Chromium codebase. |
| |
| ### Any |
| |
| ```c++ |
| 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](https://en.cppreference.com/w/cpp/utility/any) |
| |
| **Notes:** |
| *** promo |
| Banned since workaround for lack of RTTI isn't compatible with the component |
| build. ([Bug](https://crbug.com/1096380)) |
| *** |
| |
| ### Command line flags |
| |
| ```c++ |
| 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](https://abseil.io/docs/cpp/guides/flags) |
| |
| **Notes:** |
| *** promo |
| Banned since workaround for lack of RTTI isn't compatible with the component |
| build. ([Bug](https://crbug.com/1096380)) Use `base::CommandLine` instead. |
| *** |
| |
| ### Span |
| |
| ```c++ |
| absl::Span |
| ``` |
| |
| **Description:** Early adaptation of C++20 `std::span`. |
| |
| **Documentation:** [Using absl::Span](https://abseil.io/tips/93) |
| |
| **Notes:** |
| *** promo |
| Banned due to being less std::-compliant than `base::span`. Keep using |
| `base::span`. |
| *** |
| |
| ### string_view |
| |
| ```c++ |
| absl::string_view |
| ``` |
| |
| **Description:** Early adaptation of C++17 `std::string_view`. |
| |
| **Documentation:** [absl::string_view](https://abseil.io/tips/1) |
| |
| **Notes:** |
| *** promo |
| Banned due to only working with 8-bit characters. Keep using |
| `base::StringPiece` from `base/strings/`. |
| *** |
| |
| ## Abseil TBD Features {#absl-review} |
| |
| 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. |
| |
| ### 128bit integer |
| |
| ```c++ |
| uint64_t a; |
| absl::uint128 v = a; |
| ``` |
| |
| **Description:** Signed and unsigned 128-bit integer types meant to mimic |
| intrinsic types as closely as possible. |
| |
| **Documentation:** |
| [Numerics](https://abseil.io/docs/cpp/guides/numeric) |
| |
| **Notes:** |
| *** promo |
| None |
| *** |
| |
| ### bind_front |
| |
| ```c++ |
| absl::bind_front |
| ``` |
| |
| **Description:** Binds the first N arguments of an invocable object and stores them by value. |
| |
| **Documentation:** |
| * [bind_front.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/bind_front.h) |
| * [Avoid std::bind](https://abseil.io/tips/108) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `base::Bind`. |
| *** |
| |
| ### Cleanup |
| |
| ```c++ |
| FILE* sink_file = fopen(sink_path, "w"); |
| auto sink_closer = absl::MakeCleanup([sink_file] { fclose(sink_file); }); |
| ``` |
| |
| **Description:** Implements the scope guard idiom, invoking the contained |
| callback's `operator()() &&` on scope exit. |
| |
| **Documentation:** |
| [cleanup.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/cleanup/cleanup.h) |
| |
| **Notes:** |
| *** promo |
| Similar to `defer` in Golang. |
| *** |
| |
| ### Containers |
| |
| ```c++ |
| absl::flat_hash_map |
| absl::flat_hash_set |
| absl::node_hash_map |
| absl::node_hash_set |
| absl::btree_map |
| absl::btree_set |
| absl::btree_multimap |
| absl::btree_multiset |
| absl::InlinedVector |
| absl::FixedArray |
| ``` |
| |
| **Description:** Alternatives to STL containers designed to be more efficient |
| in the general case. |
| |
| **Documentation:** |
| * [Containers](https://abseil.io/docs/cpp/guides/container) |
| * [Hash](https://abseil.io/docs/cpp/guides/hash) |
| |
| **Notes:** |
| *** promo |
| Supplements `base/containers/`. |
| *** |
| |
| ### Container utilities |
| |
| ```c++ |
| auto it = absl::c_find(container, value); |
| ``` |
| |
| **Description:** Container-based versions of algorithmic functions within C++ |
| standard library. |
| |
| **Documentation:** |
| [container.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/algorithm/container.h) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `base/ranges/algorithm.h`. |
| *** |
| |
| ### FunctionRef |
| |
| ```c++ |
| absl::FunctionRef |
| ``` |
| |
| **Description:** Type for holding a non-owning reference to an object of any |
| invocable type. |
| |
| **Documentation:** |
| [function_ref.h](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/functional/function_ref.h) |
| |
| **Notes:** |
| *** promo |
| None |
| *** |
| |
| ### Random |
| |
| ```c++ |
| absl::BitGen bitgen; |
| size_t index = absl::Uniform(bitgen, 0u, elems.size()); |
| ``` |
| |
| **Description:** Functions and utilities for generating pseudorandom data. |
| |
| **Documentation:** [Random library](https://abseil.io/docs/cpp/guides/random) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `base/rand_util.h`. |
| *** |
| |
| ### StatusOr |
| |
| ```c++ |
| 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](https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/status/statusor.h) |
| |
| **Notes:** |
| *** promo |
| None |
| *** |
| |
| ### String Formatting |
| |
| ```c++ |
| absl::StrFormat |
| ``` |
| |
| **Description:** A typesafe replacement for the family of printf() string |
| formatting routines. |
| |
| **Documentation:** |
| [String Formatting](https://abseil.io/docs/cpp/guides/format) |
| |
| **Notes:** |
| *** promo |
| None |
| *** |
| |
| ### Strings Library |
| |
| ```c++ |
| 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](https://abseil.io/docs/cpp/guides/strings) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `base/strings`. |
| *** |
| |
| ### Synchronization |
| |
| ```c++ |
| absl::Mutex |
| ``` |
| |
| **Description:** Primitives for managing tasks across different threads. |
| |
| **Documentation:** |
| [Synchronization](https://abseil.io/docs/cpp/guides/synchronization) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `Lock` in `base/synchronization/`. |
| *** |
| |
| ### Time library |
| |
| ```c++ |
| 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](https://abseil.io/docs/cpp/guides/time) |
| |
| **Notes:** |
| *** promo |
| Overlaps with `Time` APIs in `base/`. |
| *** |