| # Chromium C++ style guide |
| |
| _For other languages, please see the |
| [Chromium style guides](https://chromium.googlesource.com/chromium/src/+/main/styleguide/styleguide.md)._ |
| |
| Chromium follows the [Google C++ Style |
| Guide](https://google.github.io/styleguide/cppguide.html) unless an exception |
| is listed below. |
| |
| A checkout should give you |
| [clang-format](https://chromium.googlesource.com/chromium/src/+/main/docs/clang_format.md) |
| to automatically format C++ code. By policy, Clang's formatting of code should |
| always be accepted in code reviews. |
| |
| You can propose changes to this style guide by sending an email to |
| `[email protected]`. Ideally, the list will arrive at some consensus and you can |
| request review for a change to this file. If there's no consensus, |
| `src/styleguide/c++/OWNERS` get to decide. For further details on how style |
| changes are handled and communicated, see the C++ Style Changes |
| [process documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/process/c++_style_changes.md). |
| |
| Blink code in `third_party/blink` uses [Blink style](blink-c++.md). |
| |
| ## Modern C++ features |
| |
| Google and Chromium style |
| [targets C++20](https://google.github.io/styleguide/cppguide.html#C++_Version). |
| Additionally, some features of supported C++ versions remain forbidden. The |
| status of Chromium's C++ support is covered in more detail in |
| [Modern C++ use in Chromium](c++-features.md). |
| |
| ## Naming |
| |
| * "Chromium" is the name of the project, not the product, and should never |
| appear in code, variable names, API names etc. Use "Chrome" instead. |
| |
| ## Tests and Test-only Code |
| |
| * Functions used only for testing should be restricted to test-only usages |
| with the testing suffixes supported by |
| [PRESUBMIT.py](https://chromium.googlesource.com/chromium/src/+/main/PRESUBMIT.py). |
| `ForTesting` is the conventional suffix although similar patterns, such as |
| `ForTest`, are also accepted. These suffixes are checked at presubmit time |
| to ensure the functions are called only by test files. In the rare case of |
| adding a test-only code path to an area where a testing suffix is not |
| possible, CHECK_IS_TEST() may be appropriate. |
| * Classes used only for testing should be in a GN build target that is |
| marked `testonly=true`. Tests can depend on such targets, but production |
| code can not. |
| * While test files generally appear alongside the production code they test, |
| support code for `testonly` targets should be placed in a `test/` subdirectory. |
| For example, see `//mojo/core/core_unittest.cc` and |
| `//mojo/core/test/mojo_test_base.cc`. For test classes used across multiple |
| directories, it might make sense to move them into a nested `test` namespace for |
| clarity. |
| * Despite the Google C++ style guide |
| [deprecating](https://google.github.io/styleguide/cppguide.html#File_Names) |
| the `_unittest.cc` suffix for unit test files, in Chromium we still use this |
| suffix to distinguish unit tests from browser tests, which are written in |
| files with the `_browsertest.cc` suffix. |
| |
| ## Code formatting |
| |
| * Put `*` and `&` by the type rather than the variable name. |
| * In class declarations, group function overrides together within each access |
| control section, with one labeled group per parent class. |
| * Prefer `(foo == 0)` to `(0 == foo)`. |
| * Use `{}` on all conditionals/loops. |
| |
| ## Unnamed namespaces |
| |
| Items local to a .cc file should be wrapped in an unnamed namespace. While some |
| such items are already file-scope by default in C++, not all are; also, shared |
| objects on Linux builds export all symbols, so unnamed namespaces (which |
| restrict these symbols to the compilation unit) improve function call cost and |
| reduce the size of entry point tables. |
| |
| ## Exporting symbols |
| |
| Symbols can be exported (made visible outside of a shared library/DLL) by |
| annotating with a `<COMPONENT>_EXPORT` macro name (where `<COMPONENT>` is the |
| name of the component being built, e.g. BASE, NET, CONTENT, etc.). Class |
| annotations should precede the class name: |
| ```c++ |
| class FOO_EXPORT Foo { |
| void Bar(); |
| void Baz(); |
| // ... |
| }; |
| ``` |
| |
| Function annotations should precede the return type: |
| ```c++ |
| class FooSingleton { |
| FOO_EXPORT Foo& GetFoo(); |
| FOO_EXPORT Foo& SetFooForTesting(Foo* foo); |
| void SetFoo(Foo* foo); // Not exported. |
| }; |
| ``` |
| |
| ## Multiple inheritance |
| |
| Multiple inheritance and virtual inheritance are permitted in Chromium code, |
| but discouraged (beyond the "interface" style of inheritance allowed by the |
| Google style guide, for which we do not require classes to have the "Interface" |
| suffix). Consider whether composition could solve the problem instead. |
| |
| ## Inline functions |
| |
| Simple accessors should generally be the only inline functions. These should be |
| named using `snake_case()`. Virtual functions should never be declared this way. |
| |
| ## Logging |
| |
| Remove all logging before checking in code. The exception is temporary logging |
| to track down a specific bug. This should be a rare exception, and you should |
| have a plan for how to manually collect/use the logged data. Afterwards you |
| should remove the logging. Note that logs are not present in crashes. Use |
| `base::debug::ScopedCrashKeyString` |
| ([link](https://chromium.googlesource.com/chromium/src/+/main/base/debug/crash_logging.h)) |
| for that. |
| |
| For the rare case when logging needs to stay in the codebase for a while, |
| prefer `DVLOG(1)` to other logging methods. This avoids bloating the release |
| executable and in debug can be selectively enabled at runtime by command-line |
| arguments: |
| * `--v=n` sets the global log level to n (default 0). All log statements with |
| a log level less than or equal to the global level will be printed. |
| * `--vmodule=mod=n[,mod=n,...]` overrides the global log level for the module |
| mod. Supplying the string foo for mod will affect all files named foo.cc, |
| while supplying a wildcard like `*bar/baz*` will affect all files with |
| `bar/baz` in their full pathnames. |
| |
| Rationale: |
| * Logging is expensive: binary size, runtime. |
| * Logging quickly loses utility as more components emit logs: too much noise, |
| not enough signal. |
| * Logging is often used to document impossible edge cases which should be |
| enforced with CHECKs. The latter makes it easier to reason about the code, and |
| can result in more performant binaries. |
| |
| ## Platform-specific code |
| |
| To `#ifdef` code for specific platforms, use the macros defined in |
| `build/build_config.h` and in the Chromium build config files, not other macros |
| set by specific compilers or build environments (e.g. `WIN32`). |
| |
| Place platform-specific #includes in their own section below the "normal" |
| `#includes`. Repeat the standard `#include` order within this section: |
| |
| ```c++ |
| #include "foo/foo.h" |
| |
| #include <stdint.h> |
| #include <algorithm> |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "chrome/common/render_messages.h" |
| |
| #if BUILDFLAG(IS_WIN) |
| #include <windows.h> |
| #include "base/win/com_init_util.h" |
| #elif BUILDFLAG(IS_POSIX) |
| #include "base/posix/global_descriptors.h" |
| #endif |
| ``` |
| |
| ## Types |
| |
| * Refer to the [Mojo style |
| guide](https://chromium.googlesource.com/chromium/src/+/main/docs/security/mojo.md) |
| when working with types that will be passed across network or process |
| boundaries. For example, explicitly-sized integral types must be used for |
| safety, since the sending and receiving ends may not have been compiled |
| with the same sizes for things like `int` and `size_t`. |
| * Use `size_t` for object and allocation sizes, object counts, array and |
| pointer offsets, vector indices, and so on. This prevents casts when |
| dealing with STL APIs, and if followed consistently across the codebase, |
| minimizes casts elsewhere. |
| * Occasionally classes may have a good reason to use a type other than |
| `size_t` for one of these concepts, e.g. as a storage space optimization. In |
| these cases, continue to use `size_t` in public-facing function |
| declarations, and continue to use unsigned types internally (e.g. |
| `uint32_t`). |
| * Follow the [integer semantics |
| guide](https://chromium.googlesource.com/chromium/src/+/main/docs/security/integer-semantics.md) |
| for all arithmetic conversions and calculations used in memory management |
| or passed across network or process boundaries. In other circumstances, |
| follow [Google C++ casting |
| conventions](https://google.github.io/styleguide/cppguide.html#Casting) |
| to convert arithmetic types when you know the conversion is safe. Use |
| `checked_cast<T>` (from `base/numerics/safe_conversions.h`) when you need to |
| `CHECK` that the source value is in range for the destination type. Use |
| `saturated_cast<T>` if you instead wish to clamp out-of-range values. |
| `CheckedNumeric` is an ergonomic way to perform safe arithmetic and casting |
| in many cases. |
| * The Google Style Guide [bans |
| UTF-16](https://google.github.io/styleguide/cppguide.html#Non-ASCII_Characters). |
| For various reasons, Chromium uses UTF-16 extensively. Use `std::u16string` |
| and `char16_t*` for 16-bit strings, `u"..."` to declare UTF-16 literals, and |
| either the actual characters or the `\uXXXX` or `\UXXXXXXXX` escapes for |
| Unicode characters. Avoid `\xXX...`-style escapes, which can cause subtle |
| problems if someone attempts to change the type of string that holds the |
| literal. In code used only on Windows, it may be necessary to use |
| `std::wstring` and `wchar_t*`; these are legal, but note that they are |
| distinct types and are often not 16-bit on other platforms. |
| |
| ## Object ownership and calling conventions |
| |
| When functions need to take raw or smart pointers as parameters, use the |
| following conventions. Here we refer to the parameter type as `T` and name as |
| `t`. |
| * If the function does not modify `t`'s ownership, declare the param as `T*`. |
| The caller is expected to ensure `t` stays alive as long as necessary, |
| generally through the duration of the call. Exception: In rare cases (e.g. |
| using lambdas with STL algorithms over containers of `unique_ptr<>`s), you |
| may be forced to declare the param as `const std::unique_ptr<T>&`. Do this |
| only when required. |
| * If the function takes ownership of a non-refcounted object, declare the |
| param as `std::unique_ptr<T>`. |
| * If the function (at least sometimes) takes a ref on a refcounted object, |
| declare the param as `scoped_refptr<T>`. The caller can decide |
| whether it wishes to transfer ownership (by calling `std::move(t)` when |
| passing `t`) or retain its ref (by simply passing t directly). |
| * In short, functions should never take ownership of parameters passed as raw |
| pointers, and there should rarely be a need to pass smart pointers by const |
| ref. |
| |
| Conventions for return values are similar with an important distinction: |
| * Return raw pointers if-and-only-if the caller does not take ownership. |
| * Return `std::unique_ptr<T>` or `scoped_refptr<T>` by value when the impl is |
| handing off ownership. |
| * **Distinction**: Return `const scoped_refptr<T>&` when the impl retains |
| ownership so the caller isn't required to take a ref: this avoids bumping |
| the reference count if the caller doesn't need ownership and also |
| [helps binary size](https://crrev.com/c/1435627)). |
| |
| A great deal of Chromium code predates the above rules. In particular, some |
| functions take ownership of params passed as `T*`, or take `const |
| scoped_refptr<T>&` instead of `T*`, or return `T*` instead of |
| `scoped_refptr<T>` (to avoid refcount churn pre-C++11). Try to clean up such |
| code when you find it, or at least not make such usage any more widespread. |
| |
| ## Non-owning pointers in class fields |
| |
| Use `const raw_ref<T>` or `raw_ptr<T>` for class and struct fields in place of a |
| raw C++ reference `T&` or pointer `T*` whenever possible, except in paths that include |
| `/renderer/` or `blink/public/web/`. These are non-owning smart pointers that |
| have improved memory-safety over raw pointers and references, and can prevent |
| exploitation of a significant percentage of Use-after-Free bugs. |
| |
| Prefer `const raw_ref<T>` whenever the held pointer will never be null, and it's |
| ok to drop the `const` if the internal reference can be reassigned to point to a |
| different `T`. Use `raw_ptr<T>` in order to express that the pointer _can_ be |
| null. Only `raw_ptr<T>` can be default-constructed, since `raw_ref<T>` disallows |
| nullness. |
| |
| Using `raw_ref<T>` or `raw_ptr<T>` may not be possible in rare cases for |
| [performance reasons](../../base/memory/raw_ptr.md#Performance). Additionally, |
| `raw_ptr<T>` doesn’t support some C++ scenarios (e.g. `constexpr`, ObjC |
| pointers). Tooling will help to encourage use of these types in the future. See |
| [raw_ptr.md](../../base/memory/raw_ptr.md#When-to-use-raw_ptr_T) for how to add |
| exclusions. |
| |
| ## thread_local variables |
| |
| Much code in Chrome needs to be "sequence-aware" rather than "thread-aware". If |
| you need a sequence-local variable, see |
| [`base::SequenceLocalStorageSlot`](../../base/threading/sequence_local_storage_slot.h). |
| |
| If you truly need a thread-local variable, then you can use a `thread_local`, as |
| long as it complies with the following requirements: |
| * Its type must satisfy `std::is_trivially_destructible_v<T>`, due to past |
| problems with "spooky action at a distance" during destruction. Note that |
| `raw_ptr<T>` is not a trivially-destructible type and may not be contained |
| in `thread_locals`. |
| * It must not be exported (e.g. via `COMPONENT_EXPORT`), since this may result |
| in codegen bugs on Mac; and at least on Windows, this probably won't compile |
| in the component build anyway. As a workaround, create an exported getter |
| function that creates a `thread_local` internally and returns a ref to it. |
| * If it lives at class/namespace scope, it must be marked `ABSL_CONST_INIT`, |
| as specified in |
| [the Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#thread_local). |
| * It must not be constructed inside OOM handlers or any other code that cannot |
| allocate memory, since on POSIX, construction may alloc. |
| |
| If you can't comply with these requirements, consider |
| [`base::ThreadLocalOwnedPointer`](../../base/threading/thread_local.h) or |
| another nearby low-level utility. |
| |
| ## Forward declarations vs. #includes |
| |
| Unlike the Google style guide, Chromium style prefers forward declarations to |
| `#includes` where possible. This can reduce compile times and result in fewer |
| files needing recompilation when a header changes. |
| |
| You can and should use forward declarations for most types passed or returned |
| by value, reference, or pointer, or types stored as pointer members or in most |
| STL containers. However, if it would otherwise make sense to use a type as a |
| member by-value, don't convert it to a pointer just to be able to |
| forward-declare the type. |
| |
| Headers that contain only forward declarations, such as |
| [`callback_forward.h`](../../base/functional/callback_forward.h), satisfy the |
| spirit of this rule. Note that the [Mojo bindings |
| generator](../../mojo/public/cpp/bindings/README.md#Getting-Started) |
| creates a `.mojom-forward.h` file along with every generated `.mojom.h` file |
| that can be included for forward declarations of Mojo types. |
| |
| See [these tips](c++-dos-and-donts.md#minimize-code-in-headers) for more advice |
| on minimizing code in headers. |
| |
| ## File headers |
| |
| All files in Chromium start with a common license header. That header should |
| look like this: |
| |
| ```c++ |
| // Copyright $YEAR The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| ``` |
| |
| Some important notes about this header: |
| * `$YEAR` should be set to the current year at the time a file is created, and |
| not changed thereafter. |
| * For files specific to ChromiumOS, replace the word Chromium with the phrase |
| ChromiumOS. |
| * The Chromium project hosts mirrors of some upstream open-source projects. |
| When contributing to these portions of the repository, retain the existing |
| file headers. |
| |
| Use standard `#include` guards in all header files (see the Google style guide |
| sections on these for the naming convention). Do not use `#pragma once`; |
| historically it was not supported on all platforms, and it does not seem to |
| outperform #include guards even on platforms which do support it. |
| |
| ## CHECK(), DCHECK() and NOTREACHED() |
| |
| Use the `CHECK()` family of macros to both document and verify invariants. |
| * Exception: If the invariant is known to be too expensive to verify in |
| production, you may fall back to `DCHECK()`. Do not do this unless |
| necessary. |
| * Exception: If your pre-stable coverage is too small to prevent a stability |
| risk once `CHECK()`s hit stable, and failure doesn't obviously result in a |
| crash or security risk, you may use `CHECK(Foo(), |
| base::NotFatalUntil::M120)` with a future milestone to gather non-fatal |
| diagnostics in stable before automatically turning fatal in a later |
| milestone. |
| * Historically, Chromium code used `DCHECK()` in most cases, so a great deal |
| of existing code uses `DCHECK()` instead of `CHECK()`. You are encouraged |
| to migrate to `CHECK()`s with a trailing `base::NotFatalUntil::M120` |
| argument, as there's stability risk given the under-tested invariant, or add |
| a comment explaining why DCHECK is appropriate given the current guidance. |
| |
| Use `NOTREACHED()` to indicate a piece of code is unreachable. Control flow does |
| not leave this call, so there should be no executable statements after it (even |
| return statements from non-void functions). The compiler will issue dead-code |
| warnings. |
| * Prefer to unconditionally `CHECK()` instead of conditionally hitting a |
| `NOTREACHED()`, where feasible. |
| * Exception: If your pre-stable coverage is too small to prevent a stability |
| risk once `NOTREACHED()`s hit stable, and failure doesn't obviously |
| result in a crash or security risk, you may use `NOTREACHED( |
| base::NotFatalUntil::M120)` with a future milestone to gather non-fatal |
| diagnostics in stable before automatically turning fatal in a later |
| milestone. |
| |
| Use `base::ImmediateCrash()` in the rare case where it's necessary to terminate |
| the current process for reasons outside its control, that are not violations of |
| our invariants. |
| |
| Use `base::debug::DumpWithoutCrashing()` to generate a crash report but keep |
| running in the case where you are investigating some failure but know that it's |
| safe to continue execution. |
| |
| Use `DLOG(FATAL)` (does nothing in production) or `LOG(DFATAL)` (logs an error |
| and continues running in production) if you need to log an error in tests from |
| production code. From test code, use `ADD_FAILURE()` directly. Do not use these |
| for invariant failures. Those should use `CHECK()` or `NOTREACHED()` as noted |
| above. |
| |
| For more details, see [checks.md](checks.md). |
| |
| ## Test-only code paths in production code |
| |
| Try to avoid test-only code paths in production code. Such code paths make |
| production code behave differently in tests. This makes both tests and |
| production code hard to reason about. Consider dependency injection, fake |
| classes, etc to avoid such code paths. |
| |
| However, if a test-only path in production code cannot be avoided, instrument |
| that code path with `CHECK_IS_TEST();` to assert that the code is only run in |
| tests. |
| |
| ```c++ |
| // `profile_manager` may not be available in tests. |
| if (!profile_manager) { |
| CHECK_IS_TEST(); |
| return std::string(); |
| } |
| ``` |
| |
| `CHECK_IS_TEST();` will crash outside of tests. This asserts that the test-only |
| code path is not accidentally or maliciously taken in production. |
| |
| ## Miscellany |
| |
| * Use UTF-8 file encodings and LF line endings. |
| * Unit tests and performance tests should be placed in the same directory as |
| the functionality they're testing. |
| * The [C++ Dos and Don'ts](c++-dos-and-donts.md) page has more helpful |
| information. |