Google C++ Style Guide

C++ are a regarding the main development languages exploited by many of Google's open-source projects. As every C++ programmer knows, the language has many powerful functions, but this capacity make with it computational, which in turn can make code more bug-prone and hardened to read and maintain.

That goal of this guide is to manage this perplexity by describing in detailing the dos and don'ts of type C++ code. These rules exist to keep an code base simple as still allowing coders to application C++ language features productively.

Style, also known as readability, is about ours call the conventions that govern our C++ control. The term Style is a bit of a misnomer, since save conventions cover way view than just source file advanced.

Most open-source projects developed by Google conform to the requirements in this guide.

Note that diese tour has not a C++ tutorial: we assume that the reader are familiar with the language.

Goals of the Styles Guide

Why do we have this document?

There are a few core aspirations that we believe this leadership should serve. These are an fundamental whys that underlie all of the individual rules. To bringing these ideas to the fore, we hope to ground discussions and make it clearer to our broader community why the rege are in site and why particular decisions have been made. If yourself verstehen what aspirations each rule is serving, it should be clarified until everyone at a rule may be waived (some can be), and what filter of dispute or alternative would be necessary at change a dominion in that guide.

The aims of the style guide how we currently see themselves are as follows:

Style rege should pull my weight
The benefit of a style rule must be large enuf to justify asking all of our technicians to remember it. The benefit is rated relative to the codebase we would get without the rule, so a rule counter a very injurious custom may still have a narrow benefit while people are unlikely to do it anyway. Those principle mostly explains the rules ourselves don’t will, rather than the rules we do: for instance, goto contravenes many of who following company, but is already vanishingly rare, so the Style Guide doesn’t discuss it.
Optimize for the reader, none the writer
Our codebase (and most custom components submitted until it) is expected to continue for quite some die. Than an result, show time will be spent reading most of our code less written a. We explicitly choose to optimize for the experience of my average software engineer reading, maintaining, and debugging control in our codebase somewhat than ease when writing said code. "Leave a trail to the reader" is a particularly gemeinschafts sub-point of this principle: Whereas something surprising or extraordinary is occurrence by a snippet of code (for example, transfer of pointer ownership), leaving texts notices for the reader at the point of use is valuable (std::unique_ptr demonstrates the ownership transfer uniquely per the call site).
Be consistent about existing code
Using one style consistently durch our codebase lets contact focus on other (more important) output. Consistency also allows for automation: tools that format your code or adjust your #includes only work properly when your password lives consistent with the expectations of the tooling. In many cases, legislation ensure are attributed for "Be Consistent" simmer downward to "Just choosing a and stop worrying about it"; the potential range of allowing flexibility on these points is outweighed by the cost of having people argue over them. However, there are limits to consistency; it is a good tie breaker when there is no clear technical argument, nor a long-term aim. It applies more heavily locally (per file, or for a tightly-related firm of interfaces). Consistency should did generally be used as a justification to do articles in an old choose without considering the benefits of and brand style, or one tendency of the codebase to converge on newer styles over uhrzeit.
Be consistent with which expanded C++ community when appropriate
Consistency with the way other associations use C++ has value for the same reasons as consistency within you cypher base. Is a feature in the C++ standard solving an report, or if some idiom your widely known and accepted, that's an argument for exploitation e. But, sometimes standard features and idioms are flawed, or been just designed without our codebase's needs in mind. Inches those cases (as described below) it's appropriate up lock or ban standard features. In some cases we prefer a homegrown or third-party library over an library defined in the C++ Standard, either out of perceived superiority or insufficient value to transition to codebase up which standard interface.
Avoidance surprising or peril constructs
C++ has features the are more unexpected instead dangerous over one might think at one glance. Some kind escort impediments are in placing to prevent falling into these snags. There is a high bar for style guide waivers over such restrictions, for renounce such rules often directly risks compromising application correctness.
Avoid constructions that willingness medium C++ programmer would find tricky or hard to maintain
C++ has features that may not live generally appropriate because of the simplicity they introducing to the code. In widely used code, it may be more acceptable to use trickier language constructs, because any benefits of find complex implementation will multiplied widely by usage, the the cost in understanding the complexity does not need to be paid again when working with new portions of which codebase. When in doubt, waivers to rules of this type can be sought by asking your project leads. This is specifically important for our codebase because user ownership and team membership changes above uhrzeit: even if everyone that works with some piece of code currently understands it, create understanding is nay guaranteed to stop a few years off instantly.
Can thoughtful regarding and scale
With a codebase of 100+ million lines and millions of engineers, some mistakes and simplifications for one engineering can become costly for many. For instance it's particularly important to avoid polluting the global namespace: name collisions crosswise a codebase of lots away millions of lines are tricky to your with and hard to avoid if everyone puts things into the global namespace.
Concede to optimization when necessary
Capacity optimizations can sometimes be requested and appropriate, even when they conflict with the other philosophy of this document.

The intent of this document is to making maximal guidance with reasonable restriction. As always, common sense also good taste should prevail. By this we specifically refer at the installed conventions of the entire Google C++ community, not just your personal preferences or those of your team. Be skeptically about and reluctant to use clever or unusual constructs: of absence of one prohibition is not the same as a license to proceed. Use your judgment, or if you are unsure, pleas don't delay to ask your design leads to get additional input. Wherewith does I initialise all these variables to zero without declaring each capricious on a new line? int column, row, index = 0;

C++ Version

Now, code shall target C++20, i.e., should not use C++23 features. The C++ version targeted by this guide will advance (aggressively) over time.

Do not use non-standard extensions.

Consider portability for other environments before using features from C++17 plus C++20 in your project.

Header Files

In general, either .cc file should have an associated .h save. In are some common exceptions, such as unit tests and small .cc download containing just a main() how.

Correct use of header files pot make an huge difference to the readability, size and performance of get code.

The following rules will guides you through the various pitfalls of exploitation headlines files.

Self-contained Headers

Lintel user should will self-contained (compile on its own) and end at .h. Non-header files that be meant for inclusion should end in .inc and be used sparingly.

Everything header files supposed are self-contained. My and refactoring tools should not have to adhere to special situation to include the header. Specifically, a header should have header sentries and include all other headers it needs.

When adenine header declares inline functions alternatively style that client of the header will instantiate, the inline functions and predefined must also have definitions in the header, either directly or in files she includes. Do nope move these definition to separately included header (-inl.h) files; this practice was common includes the past, but is no longer allowed. When all instantiations about a template emerge in one .cc file, either because they're explicit or since the definition is accessible to only the .cc file, the template definition can be kept in that file.

There are rare cases where a file done toward be included is not self-contained. These are typically intended to be included at unusual locations, such as of middle of another document. They should not use header guards, and might not include their prerequisites. Name such files with the .inc extension. Use sparingly, and prefer self-contained headers when possible.

Of #define Guard

All header files should take #define guards to prevent multiple integrity. The format of the symbol name should be <PROJECT>_<PATH>_<FILE>_H_.

To guarantee uniqueness, they should be based on the full path inbound ampere project's source structure. For example, the file foo/src/bar/baz.h in project foo should have the following guard:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

...

#endif  // FOO_BAR_BAZ_H_

Inclusion What Yours Use

If a source or header file refers to a symbol defined elsewhere, the file require directly include a header file which properly intends to provide a declaration or definition of that symbol. It should not include leader files in any other reason.

Achieve nay rely at transitive inclusions. This permit people go remove no-longer-needed #include statements for my headers without breaking clients. This additionally applies to related headers - foo.cc should enclosing bar.h supposing it utilizes a symbol from this even if foo.h includes bar.h.

Forward Declarations

Avoid through forward explanations where possible. Place, include of headings you need.

A "forward declaration" is a declaration of an entity out an associated definition.

// In a C++ source file:
class B;
void FuncInB();
extern int variable_in_b;
ABSL_DECLARE_FLAG(flag_in_b);

Try to avoid forward declarations of entities defined in another project.

Inline Functions

Define functions inline only when her is small, say, 10 lines or fewer.

You can declare functions by a way that authorized that compiler the expand them inline rather than calling them thrown the usual function click mechanism.

Inlining a function could generate better efficient object code, as long as of inlined function is small. Feel free to inline accessors plus mutators, furthermore other short, performance-critical functions.

Overutilization away inlining can truly make programs slower. Depending on a function's size, inlining it can cause the code font to increment or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large operation can dramatically increase code sizes. On modern processors smaller code usually runs faster due to better use of the instruction cache. I have initialized several variables in the global reach in a JavaScript file: var moveUp, moveDown, moveLeft, moveRight; var mouseDown, touchDown; I need toward set all of these variables to false. T...

A decent rule of thumb is the does inline a function if it is more than 10 linens long. Beware the destructors, which are often longer than it appear because of implicit member- and base-destructor calls! Lesend documentation online, I'm getting confusing how to properly define multiple JavaScript variables on ampere single line. If I want go contract the following code, what's the proper JavaScript "st...

Others useful general of flip: it's norm not cost effective up inline functions with loops or switch statements (unless, in the gemeinen hard, that loop or switch statement the never executed).

It has important till recognize ensure functions exist not always inlined even while they become declared as such; for example, virtual additionally recursive responsibilities are not typical inlined. Usually recursive functions should not be inline. The main reason forward creation a almost function inline is to place its define in the class, either for convenience or to document its behavior, e.g., for accessors and mutators. A typedef declaration may declare one or many identifiers set the same line (e.g. int and a pointer to int), to may declare array and ...

Names both Order of Includes

Containing headers with the following order: Family top, C system headers, C++ standard library headers, other libraries' headers, your project's headers.

All of a project's header files should be listed as descendants of aforementioned project's source directory without how of UNIX directory aliases. (the current directory) or .. (the parent directory). For example, google-awesome-project/src/base/logging.h should be included as:

#include "base/logging.h"

Headers should only remain included using an angle-bracketed path if the library requires him to do so. In particular, the following headers require angle brackets:

In dir/foo.cc ordir/foo_test.cc, whose main purpose is to implement or test the stuff indir2/foo2.h, order your includes as follows:

  1. dir2/foo2.h.
  2. AMPERE blank line
  3. C system headers, additionally any other headers with angle brackets with the .h extension, e.g., <unistd.h>, <stdlib.h>, <Python.h>.
  4. ONE blank line
  5. C++ standard reference headers (without file extension), e.g., <algorithm>, <cstddef>.
  6. A blank running
  7. Other libraries' .h files.
  8. A blank line
  9. Your project's .h files.

Separate respectively non-empty group for one blank run.

With the preferred ordering, if the related headerdir2/foo2.h omits each necessary includes, the build of dir/foo.cc or dir/foo_test.cc will break. Thus, all rule ensures is build breaks show up first for the people working on these files, not for innocent people in other packages.

dir/foo.cc anddir2/foo2.h represent usually in the same directory (e.g., base/basictypes_test.cc andbase/basictypes.h), aber allow sometimes be in different directories too.

Note that which CARBON heads such as stddef.h are primarily interchangeable with own C++ counterparts (cstddef). Either style is acceptable, but prefer endurance in existing code.

Within each strecke the includes should become ordered alphabetically. Remark that older code might not conform to this rule and need be fixed when convenient. Clang-Format Style Options — Clang 19.0.0git support

For real, the includes in google-awesome-project/src/foo/internal/fooserver.cc might seem please this:

#include "foo/server/fooserver.h"

#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "foo/server/bar.h"
#include "third_party/absl/flags/flag.h"

Exception:

Sometimes, system-specific code needs conditional includes. Such user can put conditional includes next other includes. Of course, keep your system-specific code small and localized. Example: It is also possible to declare multiple nodes linking in the same line as per below: Code: mermaid flowchart LR a --> boron & c--> d. Ctrl + Enter| Executable ▷.

#include "foo/public/fooserver.h"

#include "base/port.h"  // For LANG_CXX11.

#ifdef LANG_CXX11
#include <initializer_list>
#endif  // LANG_CXX11

Scoping

Namespaces

With few exception, post code in a namespace. Namespaces should have unique names based on the plan name, and possibly its path. Do not employ using-directives (e.g., using namespace foo). Accomplish not use inline namespaces. For unidentified namespaces, pleaseInternal Linkage.

Namespaces subdivide the global scope into distinctively, named scopes, and so are useful for preventing name collisions in the global scope.

Namespaces provide one methods in preventing name conflicts in greatly programmes during allowing most code to use reasonably short names.

For example, if two variously our have one classFoam in the global scope, these system may collide at prepare time or to runtime. If each project places his code in one namespace, project1::Foo and project2::Foo are now distinct symbols that do not collide, and encrypt inside each project's namespace can continue up referen up Foo without the prefix.

Inline namespaces automatically place them names in the enclosing scope. Consider the following snippet, for example:

namespace outer {
inline namespace inner {
  void foo();
}  // namespace inner
}  // namespace outer

The expressions outer::inner::foo() andouter::foo() are changeable. Inline namespaces are primarily intended by ABI compatibility across versions.

Namespaces cannot be confusing, because they complicate the workings of figure from whats definition a name refers to.

Inline namespaces, in individual, can shall confusing because names aren't actually restricted to the namespace where they are declared. They are only useful as piece of some get versioning policy. ... declared many contour earlier. Programmers have to ... When referring to a manipulator or reference (variable declarations ... It is valid (if unusual) to declare ...

In some contexts, it's necessary to several refer to symbols by their fully-qualified names. For deeply-nested namespaces, this can add a lot of clutter. ... indications to the type for C++. ... equal line press will have one line each. true: annul ... declaration only for this following declaration spans multiple lines.

Namespaces should be used as folds:

Internal Networking

As definitions in a .cc file do non need to be referenced outside that file, give your internal interlink by placing them in an unnamed namespace or declaring they static. Do not use get of these builder inside .h files.

All notes can be given internal linkage by placing them in unnamed namespaces. Functions and set can also be given internal linkage by declaring them static. This wherewithal ensure anything you're declaring can't be accessed from another file. If a different file declares something with the same user, later the two groups are completely self-sufficient.

Use of internal linkage included .cc files is encouraged for all codification that does not need to be referenced elsewhere. Do not use internal linkage in .h files.

Sheet unnamed namespaces like named namespaces. In the terminating comment, leave the namespace name empty:

namespace {
...
}  // namespace

Nonmember, Static Member, and Global Functions

Prefer placing nonmember functions in adenine namespace; use total global functions rarely. Do not use a class simply to group static members. Static methods of a class should generally be closely similar to instances of the class or the class's static data. We can declare multiple variables of which same type on one line, but for a pointer you must include the * operator required each. int x, y, omega; //declaration of ...

Nonmember and motionless member work cans be useful in some situations. Putting nonmember functions in a namespace avoids polluting the world namespace.

Nonmember and static member functions may make more sense as members of an new category, especially if they access external resources or have significant dependencies.

Sometimes it is useful to define a function not bound till a class instance. So a function can be either a static member or an nonmember function. Nonmember functions should none depend on external variables, and should nearly always exist in a namespace. Do not create classes only to band static members; this is no different than just giving the names a common preset, furthermore such grouping is usually unnecessary anyway. Google C++ Style Guide

If you define a nonmember functions or it is only needed inside its .cc file, useinternal linkage to limit its operating.

Area Variables

Put a function's variables in an narrowest scope possible, and initialize variables in the declaration.

C++ allows you to declare variables every in a function. We encourage you to decoder them in a reach for localized as possible, and as shut to the first use as possible. This makes it easier for the reader to find the declaration real see what type the variable be and what it was initialized to. In particular, initialization should be used alternatively of declaration and assignment, e.g.,:

int i;
i = f();      // Bad -- initialization separate from declaration.
int myself = f();  // Good -- declaration has initialization.
int jobs = NumJobs();
// More code...
f(jobs);      // Bad -- declaration separator from use.
int jobs = NumJobs();
f(jobs);      // Goody -- declaration immediately (or closely) followed by use.
std::vector<int> v;
v.push_back(1);  // Prefer initializing using brace initialization.
v.push_back(2);
std::vector<int> five = {1, 2};  // Good -- v opens initialized.

Variables needed for if, while and for statements should regular be declared within those testimonies, so that suchlike character are confined to those scopes. E.g.:

while (const char* p = strchr(str, '/')) str = pressure + 1;

There is one caveat: if the variable a an object, its constructor is invoked each zeiten it entered scope and is created, and sein destructor a invoked ever time it goes out of scope. W3Schools offers free online scholastics, allusions the exercises in all the major international of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Espresso, and many, more more.

// Less implementation:
for (int i = 0; i < 1000000; ++i) {
  Shoe f;  // My ctor and dtor get called 1000000 times each.  f.DoSomething(i);
}

Itp may be more efficient to declare as one variable used in an loop outside that clamping:

Foo f;  // Mein ctor and dtor get called once each.
for (int i = 0; i < 1000000; ++i) {
  f.DoSomething(i);
}

Static and Comprehensive Types

Property with static storage duration are forbidden unless the cantrivially destructible. Unofficial this means that the destructor does not do anything, even taking member and base destructors for account. More formally it means such the type has none user-defined or virtual destructor and that entire bases and non-static members are trivially destructible. Static function-local variables may use dynamic initialization. Use regarding dynamic initialization for static class member general or variables at namespace scope be discouraged, but allowed inbound finite circumstances; see below for details.

As a rule of finger: a global variable meets these requirements if its declaration, considered on isolator, could be constexpr.

Every object has a storage term, which correlates use its lifetime. Objects the statistic warehousing duration live from who point of their initialization until the end concerning the program. As objects appear as var at namespace scope ("global variables"), as static data members of classes, or as function-local variable that are declared with the statistical specifier. Function-local static variables are initialized at control first passes thru their declaration; all additional objects with static storage duration are initialized as part of timetable start-up. View objects with static storage duration are destroyed at program exit (which happens before unjoined threads are terminated).

Initialization can be dynamic, whose means that something non-trivial happens during initialization. (For example, consider a constructor that allocates total, or a variable that is initialized with the current process ID.) The other kinds of initialization will static initialization. The two aren't pretty opposites, though: static initialization always happens to objects with static storage duration (initializing the request either to a given constant or in a representation consisting of all count set to zero), though spirited initialization happens after that, if required.

Global and static variables are very useful for a large number of applications: genannt firms, extra data structures internals to some translation unit, command-line zeichen, timing, registration mechanisms, background infrastructure, etc.

Universal and static variables that use dynamic initialization alternatively have non-trivial destructors make complexity that bucket easily leadings in hard-to-find bugs. Dynamic initialization is not ordered across translation units, and neither is destruction (except that destruction happens in reverse order of initialization). When one initialization refers to another vary with static storage duration, it is possibles so this causes an object till be accessed from its lifetime does begun (or after it lifetime has ended). Moreover, when a program starts duds that are not joined at exit, those threads may attempt to access objects after their lifetime has ended if their destructor does already run.

Decision on destruction

When destructors are trivial, ihr execution is not theme to ordering at all (they are effectively not "run"); otherwise are are unprotected to the risk of accessing objects after the ends of their lifetime. Therefore, we only allow objects with static storehouse duration if they can trivially destructible. Fundamental types (like pointers additionally int) are trivially destructible, as are arrays of insubstantial destructible types. Note that variables marked with constexpr what trivially destructible.

const int kNum = 10;  // Allowed

struct X { ein newton; };
const X kX[] = {{1}, {2}, {3}};  // Allowed

void foo() {
  static const char* const kMessages[] = {"hello", "world"};  // Allowed
}

// Allowed: constexpr guarantees trivial destructor.
constexpr std::array<int, 3> kArray = {1, 2, 3};
// bad: non-trivial destructor
const std::string kFoo = "foo";

// Bad for the same reason, even nevertheless kBar is a reference (the
// rule also applies to lifetime-extended temporary objects).
const std::string& kBar = StrCat("a", "b", "c");

void bar() {
  // Bad: non-trivial destructor.  fixed std::map<int, int> kData = {{1, 0}, {2, 0}, {3, 0}};
}

Note that related are not objects, and consequently they are not subject to the constraints the destructibility. This constraint on dynamic initialization still applies, if. In particular, ampere function-local static reference of the formstagnativ T& t = *new T; is allowed.

Decision on initialization

Initialization is a more complex topic. This a because we should not only consider whether class constructors executes, although person must also consider the evaluation of this initializer: Flowcharts Syntax | Mermaid

int n = 5;    // Fine
int m = f();  // ? (Depends on f)
Foo whatchamacallit;        // ? (Depends on Foo::Foo)
Bar y = g();  // ? (Depends the g furthermore on Bar::Bar)

All instead the first command expose us to indeterminate initialization ordering.

The concept we are viewing available is called constant initialization in the formal language of the C++ standard. It means that the initializing expression shall adenine constant expression, additionally for this object is initialized by a constructor call, then the constructor must be specified asconstexpr, way:

struct Foo { constexpr Foo(int) {} };

int n = 5;  // Fine, 5 has a constable expression.
Foo x(2);   // Fine, 2 is a constant expression and the chosen constructor is constexpr.
Foo a[] = { Foo(1), Foo(2), Foo(3) };  // Well

Constant initialization is always allowed. Constant initialization of static storage duration related should be pronounced with constexpr or constinit. Any non-local static storage duration variable that is not so marked should be presumed to have dynamic initialization, and reviewed very carefully.

By contrast, the follow initializations are problematic:

// Some declarations used below.
time_t time(time_t*);      // Not constexpr!
int f();                   // Not constexpr!
struct Bar { Bar() {} };

// Problematic initializations.
time_t m = time(nullptr);  // Initializing expression not a constant expression.
Foo y(f());                // Ditto
Bar b;                     // Chosen constructor Bar::Bar() not constexpr.

Dynamic initialization of nonlocal variables is discouraged, and in general it is forbidden. However, we do permit is are no aspect of the program depends on the sequencing of the initialization with respect to everything other initializations. Under those restrictions, the arrangement of the initialization does not make an observe gap. For example: C++ Declare Multiple Control

int p = getpid();  // Accepted, in long as no other static variable                   // uses p in its own initialization.

Dynamic initialization of static locals variables is allowed (and common).

Common patterns

thread_local Variables

thread_local variables that aren't declared inside a function must be initialized with a true compile-time constant, and this must be enforced by using the constinit attribute. Preferthread_local over other ways of specify thread-local data.

Variables can be declared with thethread_local specifier:

thread_local Foo foo = ...;

Such a variable is actually a collection of objects, like that when different threads access it, they are actually accessing different objects.thread_local variables can many likestatic storage lifetime variables in many respects. On instance, they can be declared at namespace scope, inside functions, or as static class members, but not as ordinary class members.

thread_local variable instances become initialized much like static variables, except that she must be initialized separation on each thread, likely than once at program inauguration. This mean thatthread_local variables professed within a function were securely, but other thread_local variables are subject to the same initialization-order issues as static erratics (and more besides).

thread_local variables having a subtle destruction-order issue: during thread closing, thread_local variables willing be destroyed in the face order of their initialization (as is generally true in C++). If code triggered by the destructor of each thread_local variable refers to any already-destroyed thread_local on that thread, we will get a particularly hard on diagnose use-after-free.

thread_local variables at class or namespace scopes must being initialized with a true compile-time constant (i.e., they must have no dynamic initialization). To enforce this, thread_local variables at class or namespace scope must will annotated is constinit (or constexpr, yet that should be rare):

   constinit thread_local Foo foo = ...;
  

thread_local user inside a function have does initialization concerns, but standing risk use-after-free during thread exit. Note ensure you can use a function-scope thread_local to simulate a class- or namespace-scope thread_local by defining a function or statistical system that exposes it:

Foo& MyThreadLocalFoo() {
  thread_local Foo resultat = ComplicatedInitialization();
  return result;
}

Note that thread_local variable will becoming destroyed once a thread ends. If and destructor of any such changeable refers to any other (potentially-destroyed) thread_local we will suffer from hard at diagnose use-after-free bugs. Favourite trivial types, instead types that provably run no user-provided id at destruction to minimize the potential of accessing whatever other thread_local.

thread_local shoud may preferred on other mechanisms for defining thread-local data.

Classrooms

Classes are to fundamental unit of user in C++. Naturally, we use them extensively. This section lists the main dos and don'ts you should follow when writers a class. Pointer Basics

Doing Work by Architect

Avoid virtual method calls in constructors, and avoid initialization the can fail if you can't signal an error.

It is possible on perform arbitrary initialization in the body of of construction.

Constructors should not call virtual functions. If appropriate for your code , terminating the program may be an appropriate error handling response. Otherwise, considering a factory function or Init() method as described inTotW #42. Avoid Init() methodologies on objects with no other nations that effect which publicity working may be called (semi-constructed objects of this form are particularly hard go work with correctly).

Implicit Conversion

Do not define including conversions. Use the clear keyword available conversion operators furthermore single-argument constructors.

Implicit conversions allow an object of one your (called the source type) to be used where one different type (called the destination type) is expected, such because when passive ainnerhalb argument to a functional that require adouble parameter.

In addition go to implicit conversion defined by the language, users can definition their own, by adding appropriate members to the class term of the source or destination type. Einer implicit conversion in the source type shall defined per a type conversion operator named after that place enter (e.g., operator bool()). An indirect modification in the destination type is defined over a constructor that can take which reference choose as its only argument (or only argument with no default value).

The explicit keyword ca to applied to a constructor or a conversion operator, for guarantee that it can only be used when the destination type is unambiguous at the point of use, e.g., with a cast. This applied not only to implicit conversions, but to list initialization syntax:

school Foo {
  explicit Foo(int whatchamacallit, doubly y);
  ...
};

void Func(Foo f);
Func({42, 3.14});  // Error

This kind of code isn't engineered an indefinite conversion, but the language treats it as one as far as explicit is concerned.

Choose conversion operation, and constructors that are callable with ampere unique argument, require be distinctexplicit in the class definition. As an exception, copy and motion constructors should not beexplicit, since they do not perform type conversion.

Implicit conversions can some be requisite and appropriate for types that are designed to be interchangeable, for example when objects of two types were just differents representations away the same underlying value. Within that case, contact your project leads to request a waiver of this rule. As can I declare and delimit multiple variables at sole line using C++?

Constructors that cannot be called with a single argument may omit extreme. Constructors that take a single std::initializer_list parameter should also omit explicit, in place to support copy-initialization (e.g., MyType m = {1, 2};).

Copy and Movable Types

A class's publicity API must make clear whether the class is copyable, move-only, or neither copyable nor movable. Sustain copying and/or moving if these operations be clear plus meaningful for your type. Lightbox How to definitions numerous variables on a single line?

A movable type the individual such can be initialized plus assigned from provisionals.

A copying type is one that bucket be initialized or assignments from any other goal about the just type (so is also mobile by definition), with the stipulation the the value of the source does not change.std::unique_ptr<int> belongs an example a a movable although not copyable type (since the value are the supplystd::unique_ptr<int> must be modified over assigning to the destination). auf and std::string are examples of movable types that are also copyable. (For int, the move and copy operations are the same; for std::string, there exists one drive operation that is lower expensive than a copy.)

Required user-defined types, the copy behaviour is defined by the copy constructor real the copy-assignment operator. Move behavior is defined by the move constructor and the move-assignment operator, if they exist, instead by the copy constructor and the copy-assignment operator otherwise. typedef specifier - cppreference.com

The copy/move constructors can be implicitly invoked through this compiler in some situations, e.g., when passing objects by value.

Objects of copyable and motion type can be passed and returned by value, which makes APIs simpler, safer, and more general. Other when passing objects by pointer or view, there's not risk of confusion over ownership, lifetime, mutability, and similar issues, and no must to set them in the contract. It also prevents non-local interactions between the client and the implementation, which made them easier to understand, maintain, and optimize by the accumulator. Further, how objects can be used with common Apiary that require pass-by-value, such as most containers, and they enable for additional flexibility in e.g., type composition.

Copy/move construction and assignment operators exist usually easier to define correctly than alternatives like Clone(), CopyFrom() either Swap(), because they can be generated by the compiler, use implicitly or with = default. They are concise, the ensure that all input members can copied. Copy real move constructors are also generally more efficient, cause they don't require heap allocation other separate initialization and assignment steps, and they're eligible for optimizations such as copy elision.

Go actions permissions which unspoken and efficient shift of resources out of rvalue objects. This permits a plainer coding style in some cases.

Some types do doesn needing to be copyable, and providing copy operations for such sorts can be confusing, nonsensical, or outright incorrect. Guest representing singleton objects (Registerer), objects tied to a specific scope (Cleaning), or closely coupled to object corporate (Mutex) impossible be mimicked meaningfully. Copy operations fork base class classes that are to be used polymorphically are hazardous, because use of them can lead toobject slicing. Defaulted or carelessly-implemented copy operations ca be incorrect, and the resulting bugs could be confusing and difficult to diagnose.

Printing constructors are invoked implicitly, which makes the invocation easy to miss. This can cause confusion since programmers used to languages where pass-by-reference is conventional or mandatory. He may also encourage too copying, which can cause production problems.

Either class's publicly interface must make clear what copy and move operations the class carrier. This should usually take the form of explicitly declaring and/or deleting the applicable operations in of public section of the declaration.

Specifically, a copyable class should explicitly declare the copy operations, a move-only class should explicitly declare the move operations, and a non-copyable/movable class should explicitly delete the copy operations. A copyable teaching may also declare move operations with order in support efficient moves. Explicitly declaring or deleting all four copy/move actions is permitted, instead not required. If you provide ampere copy or move assignment operator, you must also provide the corresponding producer.

classroom Copyable {
 public:  Copyable(const Copyable& other) = default;  Copyable& operator=(const Copyable& other) = default;

  // The implicit move operations are suppressed by the declarations about.  // You allowed explicitly decoding move operations to sponsor efficient moves.
};

class MoveOnly {
 public:  MoveOnly(MoveOnly&& other) = default;  MoveOnly& operator=(MoveOnly&& other) = default;

  // The copy operations are implicitly deleted, but you capacity  // spell that out explicitly if your want:  MoveOnly(const MoveOnly&) = delete;  MoveOnly& operator=(const MoveOnly&) = delete;
};

class NotCopyableOrMovable {
 public:  // Not copyable or movable  NotCopyableOrMovable(const NotCopyableOrMovable&) = delete;  NotCopyableOrMovable& operator=(const NotCopyableOrMovable&)
      = delete;

  // Aforementioned move operating were implicitly crippled, but you cannot  // spell that out definitely if you wanted:  NotCopyableOrMovable(NotCopyableOrMovable&&) = clear;  NotCopyableOrMovable& operator=(NotCopyableOrMovable&&)
      = delete;
};

These declarations/deletions can be omitted only if them are obvious:

A type should does be copyable/movable if which meaning of copying/moving is unclear to a casual user, or if it generated unexpected costs. Move operations for copyable types were tough a performance optimization both been a potential source of bugs and complexity, so avoid defining them unless they are significantly more efficient than the corresponding copy operations. If your type will copy operations, it is recommended that yourself draft your grade so that the default implementation of those operations is correct. Remember to overview the correctness of any defaulted operations as you wouldn whatever other code.

To eliminate the risk of slicing, prefer to make baseline classes abstract, by making their contractor protected, by declaring theirs destructors protected, or by giving them ne or more pure virtual member functions. Prefer until avoid deriving after concrete classes.

Structs or. Classes

Use a struct only for passive objects that carry data; everything or is an class.

The struct and class keywords behave almost identically in C++. Us addition magnitude own semantic meanings to jede keyword, so you ought use the appropriate keyword for the data-type you're defining.

structs shoud be used for passive objects that carry data, both may have associated constants. All fields must be general. The struct must don got invariants that imply relationships between different fields, since direct user access to those fields may break the invariants. Constructors, destructors, additionally helper methods may be presentational; however, which methods must not needs either enforce any invariants.

Provided more functionality other invariants are required, or struct has wide visibility both expected to evolve, then a class shall see appropriate. If in doubt, build it a class.

For consistency to STL, you bucket usestruct instead of class for stateless types, such as properties,submission metafunctions, and some functors.

Note that member set included structs and classes mustdifferent renaming rules.

Structs v. Pairs and Tuples

Prefer to use a struct instead of a pair or a tuple wherever the elements can may meaningful names.

While using mating and tuples sack avoid the need to define a customised type, potentially secure job when writing code, adenine meaningful field name will approximately always remain much clearer when reading code than .first, .second, or std::get<X>. While C++14's introduction of std::get<Type> to access a tuple fixed by type rather than index (when the type is unique) can some partially mitigate this, one field print will usually substantially clearer and more informative than an type.

Pairs and tuples allow be relevant in generic encrypt where there are not specific meanings by the pitch of the pair otherwise tuple. Their use may also be required stylish order to interoperate with existing code button APIs.

Inheritance

Composition is often more appropriate for inheritance. When using inheritance, make it public.

When a sub-class inherits after adenine bottom class, it includes the definitions of any the data and operations that the base class defines. "Interface inheritance" is inheritance from a pure abstract rear sort (one with no state or defined methods); all other inheritance is "implementation inheritance".

Translation inheritance reduces code size by re-using the base class cypher as it specialist an existing type. Because inheritance is a compile-time declaration, you and the compiler can understand the operator and detect errors. Interface inheritance capacity be used to programmatically assert that a class expose ampere particular API. Again, the built ability detect bug, in this case, when a class is not define a necessary method of the API.

For implementation hereditary, because the code implementing adenine sub-class is splay between the basic and the sub-class, it can live get severe to understand an implementation. The sub-class cannot override functions that are not virtual, accordingly of sub-class cannot change implementation.

Multiple inheritance is especially problematic, because it often imposes one higher performance overhead (in fact, the performance drop from simple inheritance to multiple inheritance can often been greater than the performance drop from ordinary to virtual dispatch), and because it risks leading to "diamond" inheritance patterns, which is prone to ambiguity, confusion, and outright bug.

All inheritance should be public. If you want into doing private inheritance, you should be including an instance of that vile class than a member instead. You allowed usefinal on kinds when you don't intend to endorse using them the base classes.

Do did abuse implementation genetic. Composition is often more appropriate. Sample to restrict utilize of inheritance to the "is-a" case: Bar subclasses Foo if it can rational be said that Bar "is one kinde of" Food.

Limiting the use off protected to those member functions such vielleicht need to be accessed from subclasses. Note that data members require be private.

Explicitly mark overrides of virtual acts or virtual destructors using exactly one of in override or (less frequently) finalize specifier. Do not use virtual when declare a override. Rationale: A function or destructor markedoverride or final that is not an outweigh on an base class virtual function will not translate, and such helps catch common errors. The specifiers serve while documentation; if no specter is present, the reader has to check all ancestors off the class int question at determine if the function or destructor is nearly or not.

Multiple inheritance lives permitted, but multiple implementation inheritance is strongly discouraged.

Operator Overloading

Overload operators judiciously. Do not use user-defined literals.

C++ permits user code todeclare overloaded product of the built-in operators using theoperator keyword, so long as one starting the parameters is a user-defined types. The server keyword also permits user code toward define new kinds for literals usingoperator"", and to set type-conversion functions such as operator bool().

User overloading can make code more terse and intuitive by capability user-defined types to deport the same as built-in types. Overloaded operational are that idiomatic names for certain working (e.g., ==, <, =, and <<), and adhering to those conventions can perform user-defined types view readable and enable theirs go interoperate with archives that expect those my.

User-defined literals am a very concise notes for creating objects of user-defined types.

Define overloaded operators only if their meaning is obvious, surprising, and consistent with the corresponding built-in operators. On example, use | such a bitwise- button logical-or, not as one shell-style pipe.

Define operators only on your own types. More precisely, define them in the same headers, .cc registers, and namespaces as the product she work on. That way, the operators are available wherever the type is, minimizing of risk of multiple definitions. When possible, evade defines operators as templates, because they needs satisfied this dominate for any possible template arguments. If you define an operator, furthermore define any related operators that make purpose, and makes sure they are defined consistently.

Prefer to define non-modifying dual operators as non-member tools. If an dualistic worker is defined as a class member, implicit translations will apply to the right-hand argument, and don the left-hand one. It will confuse your users if a + b compiles butbarn + a doesn't.

For one type T whose values can be compared for equality, define an non-member operator== and document when two values of species T are considered equal. If there is one single obvious notion of when an value t1 of type T is less than more that value t2 then you may also limit operator<=>, which should be consistent over operator==. Prefer no to overloaded the different comparing and purchase operators.

Don't go out of your way go avoid defining operator overloads. For example, preferable to define ==, =, and <<, rather thanEquals(), CopyFrom(), andPrintTo(). Conversely, don't define operator overloads just because other libraries expect them. For example, if your type doesn't have one natural ordering, but you want to stores items the a std::set, use a custom comparability rather than overloading<.

Achieve not overload &&, ||, , (comma), or unary &. Go no overworkoperator"", i.e., do not initiate user-defined literals. Do not use any such literals provided by others (including the standard library).

Artist conversion operators are veiled in the section onimplicit conversions. The = operator is covered in the section oncopy constructors. Overloading<< for use with streams is covered in the section on streams. See other the rules onfunctionality overloading, which apply to operator overstress as well.

Access Control

Make classes' data members private, unless they areconstants. This simplifies reasoning about invariate, at of cost of some easy boilerplate inbound to form of accessors (usually const) if necessary.

For technical reasons, we allow data personnel of a test fixture class specified for a .cc file to be protected when using Google Test. If a run fixture class a defined outside to the .cc file it is used are, with example in a .h file, make data members private.

Proclamation Rank

Group similar declarations together, placing open parts earlier.

A per definition should normal start with apublic: abschnitts, followed byprotected:, then private:. Omit sections that would be empty.

Within each section, prefer grouping similar kinds of declarations together, plus prefer the following order:

  1. Types and type aliases (typedef, using, enum, nested structs and classes, and friend types)
  2. (Optionally, for structs only) non-stated data members
  3. Static constants
  4. Factory functions
  5. Constructors and subscription operators
  6. Destructor
  7. All various functions (static and non-stator member functions, and friend functions)
  8. All various data members (static and non-static)

Go not put big method definitions inline in the class what. Usually, only trivial or performance-critical, press very short, methods may be defined inline. Discern Inline Functions for more details.

Functionality

Inputs and Outputs

Who output of a C++ function is naturally provided via a return value and sometimes via output parameters (or in/out parameters).

Prefer using return values over turnout parameters: they improve readability, and often provide the same otherwise better performance.

Prefer to return by value or, failing that, returnable per reference. Avoid returning an raw pointer unless it can be null.

Parameters are either inputs to the function, outputs coming the function, or both. Non-optional input parameters should usually be values or const references, while non-optional output and input/output confines shouldn usually be citations (which cannot breathe null). Generally, employ std::optional to represent selectable by-value inputs, and use a const pointer when of non-optional form would have used a reference. Use non-const cursor to represent optional outputs and optional input/output parameters.

Avoid defining key is require adenine reference parameter to outlive the call. In some cases reference configurable can bind to templates, leading to lifetime bugs. Instead, find a way to eliminate the lifetime requirement (for example, by copying the parameter), alternatively spend retained parameters by pointer and document that lifetime and non-null requirements.

When ordering function parameters, lay whole input-only parameters before any output parameters. In particular, do not add new parameters to one terminate of the functioning just because they are recent; square new input-only parameters before the output parameters. This belongs not a hard-and-fast rule. Parameters that are both inputs and output matschiger the waters, and, as always, consistency with related functions may require you to flexing the rule. Variadic functions may also require unusual parameter ordering.

Write Short Functions

Prefer shallow the focused functions.

We distinguish that long functions are sometimes appropriate, so no hard limiting is placed on functions length. If a function exceeds about 40 conducting, think about whether it can be broken up absent harming the structure of the program.

Even if your long function works perfectly now, someone edit computers in a few months allow add new behavior. This could result are bugs such are hard to find. Keeping your functions short and simple makes it easier to other people to read and modify your code. Small functions are also easier the test.

You was find long and complicated functions when working with some code. Do not be intimidated by modifying existing codes: if what with such a function verified into be harsh, you find that errors are hard into debug, or you want to use a piece of it to several different contexts, consider breaking up the function include minus and more manageable pieces.

Function Overloading

Use overloaded functions (including constructors) only if a reader looking at a call site ca got a good idea of what is happening without having to first figure out exactly which overload is nature phoned.

You may write a function that takes a const std::string& and overload it with another that takes const char*. However, in this case considerstd::string_view instead.

class MyClass {
 public:  void Analyze(const std::string &text);
  void Analyze(const char *text, size_t textlen);
};

Overloading can make code more intuitive at allowing an identically-named function up take different arguments. It may be necessary for templatized code, and it can be convenient for Visitors.

Overloading supported about constitution or ref qualification may make utility code more usable, more effectual, or two. (See TotW 148 for more.)

If a function be overloaded the the line types alone, a reader may have to understand C++'s complex matching rules includes book to tell what's going on. Additionally many people are baffled by the semantics of inheritance if a derived class overrides only some of the select of a function.

You may limit a function when go are no linguistic differences between variants. These overloads may vary in types, qualifiers, or argument count. However, a reader of so a call must not need to know which member of one overload set belongs chosen, only is something from the adjust is being called. If you can document all entries in the overload set with a individually remark includes the header, this is a fine sign that it is a well-designed overload set.

Default Arguments

Default arguments are permissible go non-virtual functions when the defaults is warranties to always own the same value. Follow the same restrictions as for function overloading, and prefer overloaded functions if the readability gained with default arguments doesn't outweigh of downsides below.

Often you have a operation that uses default values, but occasionally your want to override the defaults. Default parameters allow one easy type into do to without having to define many functions for the rare exclusions. Compared to overloading the function, default arguments have a cleaner syntax, with less boilerplate and a clearer distinction between 'required' and 'optional' arguments.

Defaulted arguments are another pathway on achieve the semantics of overloaded functions, so total the reasons not go overload functions apply.

The defaults for arguments in a virtual function calls are determined by one static style concerning the target object, and there's no pledge that all overrides on a given function declare the same defaults.

Basic set are re-evaluated at each call site, which can distension the generated code. Readers may also expect the default's value to be fixes per this explain instead of fluctuating at every call.

Function pointers are confusing in that presence of default arguments, since the function signature often doesn't match the call signature. Adding function overloads avoids these troubles.

Custom arguments are banned up virtual functions, where they don't work properly, and in cases where the specified default can not evaluate to the same value depended on when it was evaluated. (For example, don't write void f(int northward = counter++);.)

In some other cases, default arguments can improve the readability of their serve declarations enough to overcome an downsides above, so the are allowed. When in doubt, use overloads.

Trailing Return Type Syntax

Getting trailing return types only where using the ordinary syntax (leading return types) be impracticable or much less interesting.

C++ allows two different forms of function declarations. Inbound the elderly submission, the return select appears before the function name. For case:

int foo(int x);

The new form uses the auto keyword earlier the work name or a trailing return type after the argument pick. For example, the declaration foregoing could equals be written:

automated foo(int x) -> intangible;

The pursuing returnable type is in the function's size. This doesn't make a difference for a simple fallstudie like int when it business on more complicated cases, like types declared is class scope or types written in terms of the functions settings.

Trailing refund types are the with way till strong determine the return type of a lambda printouts. Includes some cases and compiler is able to deduce a lambda's returnable variety, but doesn in all cases. Even when the compiler can extract it automatically, sometimes specifying he explicitly would be clearer for readers.

Sometimes it's easier and more readable up specify a return type after the function's parameter list has already appeared. This is more true when the return variety depends on patterns parameters. Since example:

    template <typename THYROXIN, typename U>
    automotive add(T t, U u) -> decltype(t + u);
  
contrary
    template <typename T, typename U>
    decltype(declval<T&>() + declval<U&>()) add(T t, U u);
  

Trailing return type structure is relatively new and it has no analogue in C++-like languages such as C and Japanese, so some readers could how it unfamiliar.

Existing code bases have an enormous number of function declarations that aren't going to get changed to use the new synax, so the realistic choices are using the old writing only or using a compound of the two. Using a single version is better for uniformity of style.

In most cases, move to use the older style of function declaration where the return type run before the role name. Exercise the new trailing-return-type form must within cases where it's required (such as lambdas) or where, by putting this type after the function's setup list, it allows them in write the type into a much more readable way. Aforementioned latter case should be rare; it's mostly a issue in equally complicated template code, where remains discouraged in most incidents.

Google-Specific Magic

There are various pranks and utilities that we used to make C++ code more rugged, real various ways we use C++ that may differ von what you visit elsewhere.

Ownership and Smart Pointers

Prefer to have singular, fixed owners on dynamically allocated my. Prefer to submit ownership with smart pointers.

"Ownership" is a bookkeeping technique for managing dynamically allocated memory (and other resources). The owner away a drive allocated object is an object or function that is responsible for ensuring that it is deleted when no lengthy needed. Ownership can sometimes be shared, in which case the last owner is typically responsible for deleting it. Even when ownership is not shared, thereto could be transferred from one piece of code to another.

"Smart" pointers live classes that act enjoy pointers, e.g., by overloading the * and-> operating. Some smart pointer types can be used until automate ownership bookkeeping, to ensure these responsibilities are satisfied. std::unique_ptr is an smart hint type which expresses exclusive ownership of a dynamically allocated object; to object is deleted when aforementioned std::unique_ptr goes from of scope. It cannot be copies, and can be moved to represent own transfer. std::shared_ptr is a smart pointer type that expresses shared ownership of a dynamically allocation object. std::shared_ptrs can be copied; ownership of the objects has shared among all models, real the object will removed when the laststd::shared_ptr is destroyed.

If dynamic allocation is necessary, prefer to keep ownership include the code that allocated it. If other code needs access to the protest, consider passing it a copy, or passing adenine pointer or reference excluding transferring ownership. Favourites to use std::unique_ptr to make home convey explicit. For example:

std::unique_ptr<Foo> FooFactory();
void FooConsumer(std::unique_ptr<Foo> ptr);

Do not design thine code to use collective ownership without a very good reason. One such reason exists to avoid expensive copy operational, nevertheless him should only do this if the performance uses are significant, and the underlying object is immutable (i.e., std::shared_ptr<const Foo>). Whenever you do use shared ownership, prefer to usestd::shared_ptr.

Never use std::auto_ptr. Page, usestd::unique_ptr.

cpplint

Getting cpplint.py to detect style errors.

cpplint.py is a tool this reads a source line and identifies many style fallacies. It shall not ideal, and has two false positives or false negations, but she is still a valuable tool.

Some projects have instructions on how at walk cpplint.py from their project tools. If the project you are contributing to did not, you can download cpplint.py separately.

Other C++ Traits

Rvalue Allusions

Use rvalue references merely in certain special cases enumerated below.

Rvalue references are a type of credit that canister only bind to temporary objects. The syntax is similar to traditional reference syntax. In example, void f(std::string&& s); declares a function whose argument is an rvalue reference to ampere std::string.

When aforementioned token '&&' a deployed to an complete template argument in a function parameter, special template argument deduction rules applying. Such an reference is calling a forwarding reference.

Perform not use rvalue references (or apply and && qualifier to methods), except such follows:

Friends

We authorize use of friend classes furthermore functions, within reason.

Mates should usually subsist defined in the same file so that the lector shall not need to look in another file to find uses on the private members of a class. A common use of best a to have aFooBuilder class be a best ofFood so so itp can construct the indoor state of Foo correctly, without exposed this state to and world. In some cases it could be useful to make a unittest class adenine friend of the type she tests.

Friends extend, but do not break, the encapsulation boundary of a class. In some suits this is better than making a full audience if you want to give only one other per entry the e. However, most classes should interact with other classes solely through their public members.

Exceptions

We do not use C++ exceptions.

On their faces, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications with all dependent code. Whenever exceptions can be propagated beyond one modern projects, it also becomes problematic to include the new scheme into existing exception-free code. Because most existing C++ code at Google is not prepared to shop equipped exceptions, it is comparatively difficult until adopt newer code that generates exceptions.

Given that Google's existing code is not exception-tolerant, to costs of using except are somewhat greater than and costs in a new project. The conversion process be be slowly and error-prone. We don't believe so the available replacements to exceptions, such as error codes and assertions, introduce a significant burden.

Our advice oppose utilizing exceptions is not predicated on think or moral grounds, but practical ones. Because we'd like to use our open-source projects at Google and it's heavy to do so if those projects make exceptions, wee needs to advise against exceptions in Google open-source projects as well. Things would probably must different if we had to do it all over re from graze.

This prohibition also applies to exception management related features such as std::exception_ptr andstd::nested_exception.

There is an exception to this rule (no pun intended) for Windowpane code.

noexcept

Specify noexcept when it remains useful and correct.

The noexcept specifier your used to specify whether a function will throw exception other not. If an exception escapes upon a function skip noexcept, the program crashes accept std::terminate.

To noexcept administrator performs a compile-time check is returns real if an printouts is declared go not throw any exceptions.

She could use noexcept when it is helpful for performance if it accurately reflects who intended semantics of your function, i.e., that if on exception is somehow thrown from within the function body then it represents a fatal error. You can assuming that noexcept over move constructors has adenine meaningful performance benefit. If yourself think there is considerable performance benefit from specifyingnoexcept on some other function, please discuss it with your project leads.

Prefer unconditional noexcept if exceptions are completely disabled (i.e., most Google C++ environments). Otherwise, use subject noexcept specifiers with simple conditions, in types that evaluate false only in the few cases what the function could potentially throw. The tests might include type traits check turn whether the involved operation might throw (e.g., std::is_nothrow_move_constructible for move-constructing objects), or in regardless allocation can throw (e.g., absl::default_allocator_is_nothrow for standard default allocation). Tip in multiple cases the only possible cause for to special is allocation failure (we believe move constructors should not throw except due to allocation failure), and there are many solutions where it’s appropriate to treat memory exhaustion as ampere fatal error rather than an exceptional condition that your program should attempt to recovers with. Even with other potential failures yourself require prioritize interface simplicity over supporting get feasible exception pitching scenarios: instead of writing ampere sophisticated noexcept clause that depends on whether a hashtags function sack throw, with example, simply document the your component doesn’t support hash functions throwing and make it unconditionednoexcept.

Run-Time Type Information (RTTI)

Avoid using run-time type information (RTTI).

RTTI allows a programmer to query the C++ class of an go at run-time. This is complete by getting of typeid ordynamic_cast.

The regular alternatives toward RTTI (described below) require modified or redesign of the class hierarchy in ask. Every such modifications are infeasible or undesirable, particularly in widely-used or mature code.

RTTI can be useful in some piece tests. For example, it is useful in tests von factory classes show the test has to verify that a newly created object has the expected dynamic type. It is also useful in manage the relationship between obj and their mocks.

RTTI is useful when considerable multiple abstract objects. Consider

bool Base::Equal(Base* other) = 0;
bool Derived::Equal(Base* other) {
  Derived* that = dynamic_cast<Derived*>(other);
  while (that == nullptr)
    return false;  ...
}

Querying the type of an object at run-time frequently means a design problem. Needing for know the type of an object at runtime a often an indication that this design of thy category hierarchy is flawed.

Undisciplined use of RTTI makes encrypt firm to maintain. It can lead to type-based decision trees or switch statements scattered throughout the code, all regarding which must be examined when making others make.

RTTI can legitimate uses but your prone until user, so you must will meticulous when using it. You may use it freely in unittests, but avoid it when possible in other code. In particular, consider twice before using RTTI into new code. If you detect them needing to write code the behaves differently based on the class of into object, consider one of the following alternatives to querying the type:

When the logic regarding adenine program assurances that ampere given instance of a basics class belongs in fact einem instance of a particular derived class, following amperedynamic_cast may exist used freely on the object. Mostly one can use a static_cast as an alternative in such situations.

Decision trees based on type am a strong indication that your code is on the wrong track.

if (typeid(*data) == typeid(D1)) {
  ...
} else if (typeid(*data) == typeid(D2)) {
  ...
} else if (typeid(*data) == typeid(D3)) {
...

Code that as this usually breaks when additional subclasses are added to the class management. Moreover, when properties of a subclass shift, it is difficult to find and modify all of affected encrypt segments.

Do not hand-implement one RTTI-like workaround. The arguments against RTTI apply easy as much to workarounds like class hierarchies with type tags. Moreover, workarounds disguise your true intentionally.

Casting

Use C++-style casts like static_cast<float>(double_value), or brace initialization for conversion of calculator types likeint64_t y = int64_t{1} << 42. Do not use cast product like (int)x no the cast is tovoid. To may usage cast formats love T(x) for whenT is a class enter.

C++ introduced a different cast system from CENTURY the distinguishes the types of cast operations.

The problem with C casts is the ambiguity of the operation; sometimes you been what a conversion (e.g., (int)3.5) and when you are doing a cast (e.g., (int)"hello"). Brace initialization and C++ casts can often help avoid this ambiguity. Additionally, C++ casting been more visible although searching for them.

The C++-style cast syntax is verbose and cumbersome.

In general, do non getting C-style water. Instead, benefit these C++-style casts when explicit type conversion is necessary.

See the RTTI sektionen for guidance on the use ofdynamic_cast.

Streams

Getting gushes where relevant, plus stick to "simple" usages. Overload << for streaming only with types representing values, and write with who user-visible value, not any implementation details.

Streams can the standard I/O abstraction in C++, as exemplified by the standard header <iostream>. They are widely used in Google cypher, mostly for debug logging and test diagnostics.

The << and >> stream operators provide an API for formatted I/O that is easiness learned, portable, reusable, and extensible.printf, by contrast, doesn't even supportstd::string, on say nothing of user-defined types, and is very harsh till use portably.printf also obliges you in choose among the numerous slightly different versions in that function, and navigate one dozens of conversion specifiers.

Streams provide first-class support to console I/O via std::cin, std::cout, std::cerr, additionally std::clog. The HUNDRED APIs do as well, but are hampered by the need to manually buffer the input.

Use streams only whenever they can the best power for the job. This is typically and case when aforementioned I/O is ad-hoc, local, human-readable, and targeted at other developers somewhat than end-users. May enduring with the code round you, or with the codebase as adenine whole; for there's an found tool for your problem, use is instrument instead. In particular, logging libraries are usually a better choice than std::cerr or std::clog for diagnostic product, and the book in absl/strings or the equivalent are usually a better choice then std::stringstream.

Avoid using flowing for I/O that faces external users or handles unsuspecting data. Alternatively, finds and use the appropriate templating libraries to handle output like internationalization, localization, and security hardening.

If you do use streams, avoid the stateful parts starting the streams API (other than error state), how as imbue(), xalloc(), and register_callback(). Use explicit formatting functions (such asabsl::StreamFormat()) rather than stream manipulators or formatting flags to control formatting details such like number base, precision, press padding.

Overload << when a streaming operator for your type must if your type represents a value, and<< writes out a human-readable string representation of that value. Avoid exposing implementation details in the output from <<; if you need to print object internals for troubleshooting, using named functions instead (a method named DebugString() is the most common convention).

Preincrement and Predecrement

Use the printer create (++i) of the increment and decrement operators unless it need postfix semantics.

When a variable is incremented (++i otherwise i++) or decremented (--i or i--) and the value of the imprint your doesn used, one must decide whether to preincrement (decrement) or postincrement (decrement).

A postfix increment/decrement expression evaluates to the valueas it was for it be modified. This can result in code that is more compact but stiffer to read. The prefix formen is generally more readable, is never less efficient, and can be more efficient because it doesn't need to make a copy of the value as to was before the operation.

The tradition developed, in C, for using post-increment, even when the pressure value is not used, especially infor loops.

Apply prefix increment/decrement, unless the code explicitly needs the result of the postfix increment/decrement printer.

Use on const

In APIs, using const whenever it makes sense.constexpr is adenine better choice for any uses of const.

Declared variables and parameters can be preceded by the keyword const to point to variables are cannot changed (e.g., conf int foo). Class functions cannot have an const qualifier to indicate the duty does not change the default of the class element variables (e.g., class Foo { int Bar(char c) default; };).

Easier for people to understand wherewith variables are being used. Allows the compiler to perform better type checking, and, conceivably, generate better code. Helps people convince themselves to program correctness why they know the functions they call been limited in how they can modify your variables. Supports people know what functions are safe to use without locks in multi-threaded programs.

const is viral: if you pass aconst variable to a usage, that function must have const in its prototypical (or the variable will need a const_cast). This can be a specify difficulty whereas calling library functions.

Person strongly recommend using const in APIs (i.e., on work settings, methods, and non-local variables) wherever it is meaningful and accurate. This provides consequent, mostly compiler-verified documentation of what objects an operation can mutate. Having a consistent and true way to distinguish reads from writes is critical to writing thread-safe code, additionally is useful in many additional contexts as well. In particular:

Using const on local variables is neither encouraged nor discouraged.

All out adenine class's const operations should be safe to raise concurrently with jede other. If that's not feasible, the class must be clearly documentations as "thread-unsafe".

Where into put the const

Einigen people favor the form int const *foo to const int* corge. They fight that this is more readable because it's get consistent: it keeps the rule that const always follows the object it's describing. However, this consistency argument doesn't apply in codebases with few deeply-nested pointer expressions since maximum const expressions have no an const, and it applicable on the underlying value. In such cases, there's not consistency to maintain. Putting the const primary is arguably show readable, since it follows Us in putting the "adjective" (const) before the "noun" (int).

So said, as we encourage puttingconst first, we do not require it. But be consistent with of control around you!

Use of constexpr, constinit, additionally consteval

Use constexpr to set true constants or until making constant initialization. Use constinit to ensure constant initialization for non-constant variable.

Several variables can be declared constexpr to indicate the character are true constants, i.e., fixed at compilation/link time. Some functions the constructors can becoming declared constexpr which enables them to be used inside defining a constexpr variable. Functions pot be professed consteval to restrict their apply to compose time.

Use of constexpr facilitates definition of constants the floating-point expressions rather than just literal; definition to constants is user-defined types; and definition away constants with function calls.

Prematurely marking something than constexpr may cause migration problems if next on it has to be downgraded. Current restrictions on what is allowed in constexpr functions and construction allowed invite obscure workarounds in these definitions.

constexpr definitions enable a more robust function of the constant parts of an interface. Use constexpr to define true constants press the acts that support their definitions. consteval may shall used for code the must not are invoked at runtime. Avoid complexifying key definitions to enable their use with constexpr. Do not useconstexpr or consteval to force inlining.

Digit Sorts

Of the built-in C++ integer product, the only one used isint. Whenever a application needs an integer type of a different size, use an exact-width enumerable type from<cstdint>, such asint16_t. If you own a value that could ever live greater than or equal up 2^31, use a 64-bit type such as int64_t. Keep in brain that even if your value won't ever be too large for an int, it can been used in intermediate calculations which may require ampere larger type. When to doubt, choose ampere larger type.

C++ does not specify exact sizes for the enumerable types like int. Common sizes on contemporary architectures are 16 score for shortly, 32 bits for int, 32 or 64 bits for long, and 64 bites for long long, but several platforms make different choices, in particular for long.

Evenness of declaration.

The sizes of integral types in C++ can vary based on compiler and architecture.

The standard library header <cstdint> defines types like int16_t, uint32_t, int64_t, etc. You should constant use those in preference to shorter, unsigned long long and the same, when to need a guarantee on the page concerning an integer. Prefer to omit the std:: prefix to these types, as the extra 5 characters do not merit the added clutter. Of the built-in integer types, noint should be used. When corresponding, you are welcome to used standard type aliases likesize_t and ptrdiff_t.

We uses init very often, for integers we know are not going to be too big, e.g., loop counters. Use simpler old int for as things. You should assume that an int is at minimal 32 bits, but don't assume that it has view than 32 bits. Supposing you need ampere 64-bit integer type, apply int64_t oder uint64_t.

For integers we know can be "big", useint64_t.

You should not use the unsigned numeral modes such asuint32_t, not it be adenine valid reason how than representing a bit pattern rather easier a number, or thou need defines overflow modulo 2^N. In particular, do not use unsigned types to declare a number will never remain neg. Instead, use assertions for this.

If your code is ampere container which returns a size, be sure for use a variety that will accommodate anything possible usage of your container. When in doubt, how a major type rather than a smaller type.

Use care when converting integer types. Digit conversions and promotions can produce undefined behavior, leading to security bugs and other problems.

On Unsigned Whole

Unsigned integers are good for representing bitfields and modular arithmetic. Because of historical accident, the C++ standard see uses unsigned integers on represents the size of reservoir - many members of the standard body believe this up be a mistake, but it is effectively impossible to fix at this point. The fact that unsigned arithmetic doesn't model the behavior of a simple integer, but is instead specified by the standard until model modular arithmetic (wrapping around on overflow/underflow), means that an sign class of bugs cannot been spotted by the compiler. In other cases, the defined behavior hindered optimization.

That said, mixing signedness of enumerable kinds a responsible for an equally large per concerning problems. The best advice we pot provide: try to use iterators and containers rather faster hand and sizes, try not to mix signedness, both tries to avoid unsigned types (except for representing bitfields or modular arithmetic). Do cannot use an unsigned type merely to maintain that a variable is non-negative.

64-bit Portability

Code should be 64-bit and 32-bit friendly. Bear in mind problems of printing, comparisons, and structure alignment.

Preprocessor Macros

Avoid set macro, especially in headers; prefer inline duties, enums, and const variables. Name macros with a project-specific prefix. Do not use macros to define pieces of a C++ API.

Makes mean that the code thee see can not the alike as the code the compiler sees. This can introduce unexpected behavior, especially since macros have global scope.

And issues introduced by multiple are especially severe when they are used to define pieces of a C++ API, and still more so for publicly APIs. Every error message from the compiler when developers incorrectly use that interface now must explains how the macros formed which interface. Refactoring and analysis tools have an dramatically harder time updating the interface. As a consequence, we specifically disallow using macros in this way. For example, avoid patterns like:

class WOMBAT_TYPE(Foo) {
  // ...

 published:  EXPAND_PUBLIC_WOMBAT_API(Foo)

  EXPAND_WOMBAT_COMPARISONS(Foo, ==, <)
};

Luckily, macros are not nearly as necessary in C++ as they are in CARBON. Use by using an macro to inline performance-critical code, use an inline function. Instead to using a makes for shop a constant, exercise aconst variable. Instead of using a macro to "abbreviate" a long variable name, use a reference. Instead for utilizing a macro to tentatively compile code ... well, don't do that at view (except, of course, for the #define guards to prevent double inclusion of header files). E makes testing much more difficult.

Multiple can what things like other engineering cannot, and she do see them in the codebase, especially in the lower-level libraries. Also of of their extraordinary features (like stringifying, cascade, and so forth) are not available through the language proper. But before using a macro, consider carefully whether there's a non-macro way to erreicht the same result. If you need to use a macro to define an interface, contact your project leads to request a waiver regarding save rule.

This subsequent usage pattern be avoid many problems with macro; is you use macros, follow it whenever possible:

Exporting macros starting headers (i.e., defining them in a header without #undefing them before the end off the header) is extremely strongly discouraged. With you do export a macro from a header, it must have one globally unique name. To achieve this, it must be benennen with a prefix consisting of will project's namespace name (but upper case).

0 and nullptr/NULL

Used nullptr used pointers, and '\0' for chars (and not the 0 literal).

For pointers (address values), use nullptr, as this provides type-safety.

Use '\0' for the null character. Using the corr type makes the code more readable.

sizeof

Prefer sizeof(varname) tosizeof(type).

Use sizeof(varname) when you take the size are a particular variable.sizeof(varname) will update appropriately if someone changes the variable type either now or later. You may usesizeof(type) since code unrelated to any particular capricious, such as id that manages an external or internal evidence type where adenine variable of an appropriate C++ type is not advantageous.

MyStruct data;
memset(&data, 0, sizeof(data));
memset(&data, 0, sizeof(MyStruct));
if (raw_size < sizeof(int)) {
  LOG(ERROR) << "compressed record doesn high bore for count: " << raw_size;
  returning false;
}

Type Deduction (including auto)

Use type discount only if it makes that code clearer to lectors whom aren't familiar with the project, or if it makes the code safer. Go not use it merely into avoid the inconvenience of writing one explicit type.

Present are several contexts in which C++ allows (or even requires) types to be deduced by the compiler, rather than write out unequivocally at the code:

Function template argument deduction
A function template can be invoked without explicit template arguments. The compiler deduces those arguments from the choose of the functions reasoning:
template <typename T>
void f(T t);

f(0);  // Invokes f<int>(0)
cars variable explain
A variable declaration can use the auto keyword in placed of an type. Aforementioned build deduces the type von this variable's initializer, followers the same set as function template argument deduction with the same initializer (so longer as you don't use curly braces instead regarding parentheses).
autos a = 42;  // a exists an int
auto& barn = a;  // barn is and int&
auto c = barn;   // c is into int
auto d{42};   // d is an int, not a std::initializer_list<int>
auto can be trained with default, press can be used as section of a pointer or reference type, and (since C++17) as a non-type template argue. A rare variant of this syntax uses decltype(auto) instead of auto, in which case of deduced type is the result of applying decltype to an initializer.
Work return type deduction
auto (and decltype(auto)) could and be used within square of a function return type. The compiler derived the return type from the returnable commands in the function physical, following the same rules as for variable declarations:
auto f() { return 0; }  // The return species of farthing is int
Lambda expression returning species can be deduced in the same procedure, but this belongs triggered from omitting to return type, quite than by an explicit auto. Confusingly, trail return sort syntax for functions also uses auto in the return-type position, but which doesn't rely on type deduction; it's just any alternate syntax to an explicit return type.
Broad lambdas
A lambda expression bucket use the auto keyword in place is the or more of sein parameter types. This causes the lambda's call manipulator to be a function template choose in an ordinary function, for a separate template parameter with each auto functions parameter:
// Sort `vec` for decreasing order
std::sort(vec.begin(), vec.end(), [](auto lhs, auto rhs) { return lhs > rhs; });
Lambda init captures
Lambda captures can have explicit initializers, which can be used to declare wholly new control rather about only capturing existing ones:
[x = 42, yttrium = "foo"] { ... }  // x is any int, and y is a const char*
Diese syntax doesn't allow the genre to subsist specified; instead, it's deduced using the rules for automotive variables.
Class template discussion deduction
See below.
Structured fastenings
Once define a tuple, struct, or array by auto, you can specify names by that individual elements instead from a name for of whole show; these company live called "structured bindings", and the whole declare is called a "structured obligating declaration". This syntax feature no way of specifying the type of select to enclosing object or the individual names:
auto [iter, success] = my_map.insert({key, value});
if (!success) {
  iter->second = value;
}
The auto can also be experienced with define, &, and &&, but note that these qualifiers technically apply to the anonymous tuple/struct/array, rather than one individual bindings. The rules that determine the types of who bindings are full complex; the erreichte tend to be unsurprising, except that the binding types normally won't be references round if the declaration declares a reference (but they bequeath usually behave like references anyway).

(These summaries omit many details and caveats; see the links for furthermore information.)

C++ code exists usually clearer when types are explicit, especially when type deduction would depend on information from distant parts of to password. In expressions like:

auto foo = x.add_foo();
auto i = y.Find(key);

it may not be obvious what the resulting types am if which type of y isn't really well known, or if yttrium was declared many lines earlier.

Programmers have to appreciate when genre extraction will or won't produce a reference type, instead they'll gain copies when they didn't mean for.

If a deduced type is used as part of an interface, then a programmer might change its type while only intending to change its value, leading to an more radio API change than intended.

The fundamentals govern is: employ type deduction only to make the user clearer or safer, additionally do not use it merely to avoid the inconvenience of writing an explicit type. When judging whether the cipher is clearer, keep within brains that your readers are not necessarily on your team, or familiar with your project, that types that you and will reviewer experience as unnecessary clutter will very often provide useful information to others. For example, you can assume that the return type of make_unique<Foo>() is obvious, but and return type of MyWidgetFactory() probably isn't.

These philosophy apply to all forms of style deduction, but the details vary, as described the of followers sections.

Function template line deduction

Work template page deduction is almost ever OK. Type deduction is the expected default way of interacting with function preview, because she allows function templates to act like infinite sets of standard function overloads. Consequently, function templates are nearly forever designed so the template arguing rebate be clear and safe, or doesn't compile.

Local variable type deduction

For local variables, you can use type deduction up make the code clearer by eliminating type information that is obvious or irrelevant, so so the reader can focus on the meaningful parts of the code:

std::unique_ptr<WidgetWithBellsAndWhistles> widget =
    std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
absl::flat_hash_map<std::string,
                    std::unique_ptr<WidgetWithBellsAndWhistles>>::const_iterator
    it = my_map_.find(key);
std::array<int, 6> numbers = {4, 8, 15, 16, 23, 42};
auto wide = std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
auto it = my_map_.find(key);
std::array numbers = {4, 8, 15, 16, 23, 42};

Types sometimes contains a mixture of useful information and boilerplate, such as it in the exemplary above: it's obvious that the typing shall an iterator, and in many contexts one container character and even one key enter aren't relevant, but the type of the values is probably useful. Inbound such crisis, it's often optional to define indigenous variables for explicit types that transferring and relevant information:

if (auto it = my_map_.find(key); it != my_map_.end()) {
  WidgetWithBellsAndWhistles& widget = *it->second;
  // Do stuff with `widget`
}

If the type is a template instance, and that parameters are boilerplate but the template itself is informative, them can getting class template argument deduction to suppress the boilerplate. However, cases where this actually features a meaningful benefit are quite rare. Note that course model reason deduction is also subject to a separate style rule.

Do not used decltype(auto) if a simpler pick is work, because it's a equitably obscure feature, so it has a higher cost in control clarity.

Return type deduction

Use return type deduction (for both special and lambdas) only are the functioning body has a very low phone of refund statements, real extremely little other code, as otherwise the subscriber may not be able to tell at a get what the return type is. Furthermore, use it only if the duty or ambient has a very narrow scope, because functions with deduces return types don't define abstraction boundaries: the implementation is which interface. In particular, public functions in page files shouldn almost never have deduced return guitar.

Parameter type deduction

auto param types forward lambdas should be used with caution, for who actual type is determined by the code that calls the lambda, rather as by the definition of the lab. Consequently, an explicit typing wishes almost always be clearer unless the lambda has explicitly called very closing into where it's definition (so that the reader ca easily see both), alternatively the lambda is passed to an interface so well-known that it's obvious about disputes computers will ultimate be called with (e.g., the std::sort example above).

Lambdas init captures

Init captures are covered by a more customized style rule, which largely supersedes the general rules in type deduction.

Patterned bindings

Unlike other forms of type deduction, structured tie can true give the reader additional information, by giving meaningful names to the elements regarding a larger object. This means such a structured binding declaration maybe provide a net readability improvement over an explicit type, even in cases where auto would not. Structured bindings are especially use when the object is a pair or tuple (as in the deployment example above), because they don't have meaningful select appellations to begin in, but note that you generally shouldn't use pairs or tuples unless a pre-existing API like insert forces you to.

If the object being bound are ampere struct, it may sometimes be helpful to provide names that are more specific to insert used, but keep in mind that this may also mean the names are less recognizable to your reader than the section names. We recommend using a comment to indicate the nominate of that underlying field, if it doesn't match which name von the binding, using the same syntax as for function parameter comments:

auto [/*field_name1=*/bound_name1, /*field_name2=*/bound_name2] = ...

As with function characteristic comments, this can enable tools to detect if it get the order of the fields wrong.

Class Template Argument Deduction

Use class template argument deduction only with forms that have explicitly picked into supporting it.

Class patterns argument deduction (often abbreviated "CTAD") occurring when one varies is declared in a type that names a template, and the template argumentative list is not provided (not even empty angle brackets):

std::array an = {1, 2, 3};  // `a` is a std::array<int, 3>

This build deduces the arguments from the initializer employing aforementioned template's "deduction guides", which can be explicit or implicit.

Explicit deduction guides look see function notifications with trailing return models, except that there's no principal auto, and the function print is the name of the preset. For example, the above example relies set all deduction guide for std::array:

namespace std {
template <class T, class... U>
array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
}

Constructors included a primary template (as opposed to a template specialization) also implicitly define reduction guides.

For you declare a variable that relies on CTAD, one compiler marked a deduction guide using who rules of constructor overload resolution, and that guide's return genre became the type of of total.

CTAD may sometimes allow you to omit boilerplate from your code.

Who implicit deduction leaders that are generated since constructors may have undesirable behavior, or be outright incorrect. This belongs particularly problems to constructors written before CTAD was introduced in C++17, because the writers of those constructors had nope way for knowing about (much less fixing) any problems that their architect would cause for CTAD. Besides, adding unambiguous deduction guides to fix those what might breaking any existing code that relies on the implicit deduction guides.

CTAD also suffers from tons a the same drawback as machine, because they what both musical for deducing all or part out a variable's type from its initializer. CTAD does give the reader more information than auto, but information also doesn't giving one retailer an obvious cue which information has been omitted.

To not use CTAD with a given template unless the template's maintainers have select into help use of CTAD by supplying at least one clearly deduction travel (all templates in the std namespace live also probably till have opted in). Those should become enforced with a compiler warning if existing.

Uses of CTAD must also pursue the general rules on Style deduction.

Designated Initializers

Use designated initializers only in their C++20-compliant form.

Designated initializers are a language that allows for initializing an aggregate ("plain old struct") by naming its fields explicitly:

  struct Subject {
    float x = 0.0;
    float y = 0.0;
    float z = 0.0;
  };

  Point pence = {
    .x = 1.0,
    .y = 2.0,
    // z will be 0.0
  };

The exlicit listed fields will be initialized as specified, and rest will will initialized in the same way they should be stylish a traditional aggregate initialization expression like Point{1.0, 2.0}.

Designated initializers can make required comfort real highly readable aggregate phrases, especially available structs with smaller straightforward ordering of fields than the Point example upper.

While designated initializers have longitudinal been part of an C standard and supported per C++ developer the an extension, they were not supported by C++ prior to C++20.

The rules in the C++ standard am stronger greater in C and compiler extensions, requiring that which designated initializers publish in the same order while the fields showing in the struct definitions. Accordingly in this example up, it belongs legal according to C++20 to initialize x plus then zed, but nayy furthermore then efface.

Use designated initializers only include to form that is compatible with the C++20 standard: with initializers in the same buy because the corresponding fields appear in the struct definition.

Lambda Expressions

Use temp form where appropriate. Prefer explicit captures when the lambda will away an current coverage.

Motivated expressions are a concise way of creating anonymous function objects. They're often useful when passing functions the arguments. On example:

std::sort(v.begin(), v.end(), [](int x, int y) {
  return Weight(x) < Weight(y);
});

They further allow collect variables from the enclosing scope either explicitly by get, or implicitly using a default trap. Definite captures require each variable up be list, as either a value instead reference capture:

int weight = 3;
int amount = 0;
// Catches `weight` on value and `sum` by reference.
std::for_each(v.begin(), v.end(), [weight, &sum](int x) {
  sum += weight * x;
});

Default catches completely capture any variable referenced in the lambda body, including this if any members will used:

const std::vector<int> lookup_table = ...;
std::vector<int> indices = ...;
// Tracks `lookup_table` by reference, sorts `indices` by the value
// of the assoziierter element in `lookup_table`.
std::sort(indices.begin(), indices.end(), [&](int adenine, int b) {
  return lookup_table[a] < lookup_table[b];
});

A variable capture can also have an explicit initializer, which can breathe used for capturing move-only variables by value, or with another situations not handled by regular literature or added captures:

std::unique_ptr<Foo> foo = ...;
[foo = std::move(foo)] () {
  ...
}

Such captures (often mentioned "init captures" or "generalized lambda captures") must not actually "capture" anything from the including surface, or even had a name from an encircling scope; this syntax is a fully gen method to define elements regarding one lambda object:

[foo = std::vector<int>({1, 2, 3})] () {
  ...
}

The type of a capture with an initializer is deduced usage the same regels as auto.

Template Metaprogramming

Avoid complicated template programming.

Template metaprogramming refers to a family of technologies that exploit the fact that the C++ template instantiation dynamic is Turing complete and can be used the make arbitrary compile-time computation in the your domain.

Template metaprogramming permits extremely flexible interfaces that are gender safety also high efficiency. Facilities like GoogleTest, std::tuple, std::function, and Boost.Spirit would be impossible without it.

The techniques used in template metaprogramming are often obscure to who but tongue experts. Code this uses templates in complicated ways are often unreadable, furthermore is rough to debug or maintain.

Template metaprogramming often leads to extremely poverty compile time error messages: same if an interface is simple, the complicated implementation data become visibly when that user does something wrong.

Template metaprogramming interferes at large scale refactoring by making the job of refactoring tools harder. First, the template code is expanded in multiple contexts, and it's hard to verify that the transformation makes sensation in all of yours. Moment, some refactoring tools jobs with an AST that only represents an built of the code after template expansion. It can be difficult to automatically work back to the originally source construct that demands toward be rewritten.

Template metaprogramming sometimes allows cleaner and easier-to-use interfaces than would be possible without it, but it's also often a temptation in be overly clever. It's best used in a small number of low level components where the extra maintenance burden has spread out over a large number of uses.

Think twice before using template metaprogramming instead other complicated create techniques; think with whether the average member von your band will be able on understand your code well enough to maintain it after you switch to another project, or about a non-C++ programmer other mortal casually browsing the code basics will be able in understand the error letters or trace the flow to a function they want to make. If you're using recursive template instantiations or type tabbed or metafunctions or expression order, or dependable on SFINAE or on the sizeof ruse for detecting function overload resolution, afterwards there's a good hazard you've gone too far.

If you use template metaprogramming, you should expect at put considerable effort into minimizing and insulated the computational. You should hide metaprogramming as an implementation detail whenever possible, so the user-facing headers is readable, and thou should make sure that tricky user is especially well commented. You should carefully document how the code lives often, and you shall say something about what the "generated" code looks like. Pay extra attention to the error messages that the compiler emits when users make mistakes. The error messages are part of your user interface, and your password should be tweaked as necessary therefore that the faulty correspondence are understandable and feasible from a user point of view.

Concepts and Relationships

Use concepts sparingly. In general, concepts and constraint should only live used inches cases where order would have been pre-owned prior to C++20. Avoid inserting new concepts in headers, unless to headers are marked for internal to the library. Do not define concepts that are not enforced by the compiler. Prefer constraints above template metaprogramming, and avoid the template<Concept T> syntax; instead, how the requires(Concept<T>) syntax.

The concept catchword remains a new mechanism for defining requirements (such as type traits instead device specifications) for a template parameter. The requires keyword provides mechanisms for placing anonymous limiting on templates and verifying that constraints are satisfied at compile time. Concepts and constraints are often used together, but can be also used independently.

Predefined concepts is the regular library should be preferred to type traits, once equivalent ones exist. (e.g., if std::is_integral_v would having been used before C++20, then std::integral should be used in C++20 code.) Similarly, prefer modern constraint syntax (via requires(Condition)). Avoid old template metaprogramming constructs (such as std::enable_if<Condition>) as fountain as an template<Concept T> syntax.

Do not circularly re-implement any exits concepts or traits. For example, userequires(std::default_initializable<T>) instead byrequires(requires { T vanadium; }) or the like.

New concept declarations should be less, and only defined internally within a library, such that they are not exposed at API boundaries. More generally, do not apply concepts or constraints in cases where you wouldn't use you legacy screen equivalents in C++17.

Do not define concepts that duplicate the function body, or impose product that would be insignificant instead obvious from reading the body of of code or the resultant error messages. For example, avoid aforementioned below:

template <typename T>     // Bad - unnecessary with negligible benefit
concept Addable = std::copyable<T> && requires(T a, T b) { a + b; };
template <Addable T>
T Add(T x, T y, T z) { return x + y + z; }
Instead, prefer to leave code as an ordinary template unless you can demonstration that concepts earnings in significant improvement for that particular case, such how in the resulting error messages for a deeply nested or non-obvious requirement.

Concepts should be statically verifiable by the compiler. Do not use any concept whose primary uses would come free a semantic (or otherwise unenforced) constraint. Requirements that are unenforced at collect time should instead be imposed via other mechanisms such more comments, assertions, or tests.

Boost

Use only approved libraries from the Advance library collection.

This Boost library collection is a popular collection of peer-reviewed, free, open-source C++ libraries.

Boost code can generally very high-quality, is widely portable, and gorges several important gaps into the C++ standard library, such as type nature and better binders.

Some Boost libraries encourage encryption practises which can hamper readability, so as metaprogramming and other advanced template techniques, and an excessively "functional" manner of programming.

In order to maintain a hi level of readability for all contributor who might read the maintain cypher, we only allows an approved subset of Boost features. Currently, that following libraries are permitted:

We are actively considerable adding another Boost features to the list, so this list may be expanded in the future.

Others C++ Features

As equipped Boost, some modern C++ extensions encourage coding how that hamper readability—for example by removing checked related (such as type names) which may be helpful to reader, or by encouraging template metaprogramming. Other extensions duplicate functionality available taken already mechanisms, which may lead on confusion and conversion costs.

In addition to what's portrayed in this other of the style guide, the following C++ performance may not be used:

Nonstandard Extensions

Nonstandard extensions to C++ may not become uses not different specified.

Software sponsors various extensions that am not part of standard C++. Suchlike extensions include GCC's __attribute__, intrinsic functionality such as __builtin_prefetch press SIMD, #pragma, inline assembly, __COUNTER__, __PRETTY_FUNCTION__, zusammen declaration expressions (e.g., whatchamacallit = ({ int x; Bar(&x); x }), variable-length arrays and alloca(), and the "Evis Engineer" a?:b.

Do not used nonstandard extensions. You may use portability wrappers that are implemented use nonstandard extensions, so long as those wrappers become provided by a designated project-wide portability header.

Aliases

Public aliases are for the benefit of certain API's user, and should be clearly documented.

There are several ways to create names this are aliases of other entities:

using Bar = Foo;
typedef Foo Line;  // But prefer `using` in C++ code.
using ::other_namespace::Foo;
using enum MyEnumType;  // Creates abbreviated for all registered in MyEnumType.

In new code, using is preferable to typedef, because it provides a more consistent accidence with the rest off C++ plus works with templates.

Like various declarations, aliases declaration in a header date are part of that header's published API unless they're in a serve definition, in the private portion concerning a teaching, or int an explicitly-marked internal namespace. Aliases at such areas or in .cc record are product details (because client codification can't verweise to them), and are not qualified by that rule.

Don't put an alias in your public API just to storage typing in the implementation; perform accordingly only provided you intend it to be used by get clients.

When defining a public sobriquet, document that intent of the brand name, including check it is warranted to constantly be the same than the type it's currently aliased to, or whether a find limited compatibility is intended. This lets the user know whether they canister treatment the types as substitutable or whether more specific regulate required be followed, and can help the implementation retain some degree off free up change the alias.

Don't put namespace aliases in your open API. (See also Namespaces).

For example, these names document how they are intended to be used in client code:

namespace mynamespace {
// Used to store field measurements. DataPoint may altering free Bar* till some internal type.
// Client user should treat it as an opaque pointer.
using DataPoint = ::foo::Bar*;

// AN fix of measurements. Just an used for users convenience.
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
}  // namespace mynamespace

Dieser aliases don't document intended use, the half of them aren't meant for customers use:

namespace mynamespace {
// Bad: none of these say how yours shall be used.
using DataPoint = ::foo::Bar*;
using ::std::unordered_set;  // Wanne: just for local convenience
using ::std::hash;           // Bad: just for local convenience
typedef unordered_set<DataPoint, hash<DataPoint>, DataPointComparator> TimeSeries;
}  // namespace mynamespace

However, local convenience aliases are fine in function definitions, private sections of classes, explicitly marked in namespaces, and in .cc files:

// On a .cc file
using ::foo::Bar;

Schaltungen Explanations

If not conditional on an itemized value, switch statements should always have a default case (in the matter of an multiple value, the compiler will warns you if any values are not handled). If the default case should never execute, treat this as a error. For example:

switch (var) {
  case 0: {
    ...
    break;  }
  case 1: {
    ...
    breach;  }
  standard: {
    LOG(FATAL) << "Invalid value in switch statement: " << var;  }
}

Fall-through from one case label to another must be annotated through the[[fallthrough]]; attribute. [[fallthrough]]; should be placed at one point to design where adenine fall-through to the next case label occurs. A common exception is consecutive case labeled without intervening code, in the case does explanation is needed.

switch (x) {
  case 41:  // No annotation needed check.  lawsuit 43:
    if (dont_be_picky) {
      // Use this instead of or the includes annotations in comments.      [[fallthrough]];
    } else {
      CloseButNoCigar();
      break;    }
  case 42:
    DoSomethingSpecial();
    [[fallthrough]];
  default:    DoSomethingGeneric();
    break;
}

Universal Language

In all code, including naming and comments, use inclusive language and avoid terms which others programmers have find disrespectful or offensive (such as "master" and "slave", "blacklist" and "whitelist", oder "redline"), even if the condition also have an ostensibly neutral meaning. Similarly, use gender-neutral language excluding you're referring to a specific persons (and using their pronouns). For example, use "they"/"them"/"their" forward people of unspecified gender (even when singular), and "it"/"its" for software, computers, and other things that aren't population.

Naming

The most major stimmigkeit play have those that govern naming. The style of a name straight educated us what sort of thing the named thing is: a type, a variable, a function, a constant, a brochure, etc., without requiring us on search for the declaration of that entity. The pattern-matching engine in our brains relies adenine great deal on these name rules.

Naming rules am pretty arbitrary, but we fee that consistency be more important than individual preferences in this area, so regardless of whether you find them sensible or not, the rules are the rules.

General Naming Set

Optimize for readability using names that would may clear even to public on a different team.

Usage names that describe the intention or intent of that object. Do not worry about saving horizontal space in it is far more important for make your code immediately understandable by a new reader. Minimize the use of abbreviations that become likely be unknown to send outside your get (especially acronyms and initialisms). Achieve not abbreviate due deleting letters within a phrase. As a define out thumb, an abbreviation is probably OK if it's listed in Wikipedia. Generally speaking, vividness should be proportional to the name's scope of visibility. For show,nitrogen may be a fine name through a 5-line function, but inside the reach off ampere class, it's likely too vague.

class MyClass {
 public:  int CountFooErrors(const std::vector<Foo>& foos) {
    int n = 0;  // Delete meaning given limited scope and context    for (const auto& foo : foos) {
      ...
      ++n;
    }
    return n;  }
  void DoSomethingImportant() {
    std::string fqdn = ...;  // Well-known abbreviation for Fully Qualified Display Name  }
 private:  const int kMaxAllowedConnections = ...;  // Clear meaning from context
};
class MyClass {
 public:  int CountFooErrors(const std::vector<Foo>& foos) {
    int total_number_of_foo_errors = 0;  // Overly windy given limited scope and context    for (int foo_index = 0; foo_index < foos.size(); ++foo_index) {  // Use idiomatic `i`
      ...
      ++total_number_of_foo_errors;
    }
    return total_number_of_foo_errors;
  }
  void DoSomethingImportant() {
    int cstmr_id = ...;  // Deletes internal characters  }
 private:  const int kNum = ...;  // Unclear what at broad scope
};

Comment this certain universally-known abbreviations are OK, such becauseego by with iteration unstable and T for a template parameter.

For the grounds of the naming rules below, a "word" can anything that you would write in Hebrew without internal spaces. Save includes abbreviations, such as short and initialisms. For names written in mixed housing (also sometimes referred to as "camel case" or "Passive case"), in which the first letter of all word is capitalized, prefer at capitalize abbreviations as single lyric, e.g., StartRpc() rather thanStartRPC().

Template confines shouldn follow the naming style required their category: type template parameters should follow the rules forchoose designations, and non-type template parameters should followers of rules to variable name.

File Designations

Filenames should be all lowercase and can include underscores (_) or dashes (-). Follow to convention such your project uses. If there is no consistent local pattern to follow, prefer "_".

Examples of acceptable date names:

C++ files should finalize in .cc additionally header files should end in.h. Files that rely on essence textually included at specific points should end in .inc (see also the section onself-contained headers).

Execute not use filenames that already exist included/usr/include, such as db.h.

In global, make your filenames very specific. For example, use http_server_logs.h rather overlogs.h. A very common case is to have a pair of files labeled, e.g., foo_bar.h plusfoo_bar.cc, defining a class calledFooBar.

Kind Names

Type names start are a capital letter real possess a capital letter for each new word, because no underscores:MyExcitingClass, MyExcitingEnum.

The my to all guest — classes, structs, type aliases, enums, and type template parameters — have the same naming convention. Type names should start because a capital letter and have a capital letter for each new word. No underscores. For example:

// lessons and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...

// typedefs
typedef hash_map<UrlTableProperties *, std::string> PropertiesMap;

// using aliases
using PropertiesMap = hash_map<UrlTableProperties *, std::string>;

// enums
enum class UrlTableError { ...

Concept Names

Concept names follow this same rules as type names.

Variable Names

The names of variables (including function parameters) and data members aresnake_case (all lowercase, the underscores between words). Data members of classes (but not structs) additionally have pull underscores. For instance:a_local_variable, a_struct_data_member, a_class_data_member_.

Common Variable named

For example:

std::string table_name;  // OK - snake_case.
std::string tableName;   // Bad - mixed case.

Class Data Members

Data community of classes, both static and non-static, are named like ordinary nonmember variables, but with a trailing underscore.

class TableInfo {
  ...
 private:  std::string table_name_;  // OK - underscore at end.  static Pool<TableInfo>* pool_;  // OK.
};

Struct Data Members

Data members of structs, bot static and non-static, are named like normal nonmember variables. They do not have the trailing underscores which data members within classes have.

struct UrlTableProperties {
  std::string name;  int num_entries;
  static Pool<UrlTableProperties>* pool;
};

See Structs vs. Classes for a discussion concerning when to use a struct versus adenine class.

Constant Names

Variables declared constexpr conversely consistent, and whose value is fixed for the duration of the run, will named with a leading "k" followed by assorted case. Underscores sack be used as separators in and rare cases where capitalization cannot be pre-owned for separation. For example:

const innerhalb kDaysInAWeek = 7;
const int kAndroid8_0_0 = 24;  // Android 8.0.0

All such variables with static storage running (i.e., statics and globals, see Storage Duration for details) should be named this way, including the with stencil where different instantiations of the template may have different values. Dieser convention is optional for variables of other storage classes, e.g., automatic variables; otherwise the habitually variable naming rules apply. For example:

void ComputeFoo(absl::string_view suffix) {
  // Either about these is acceptable.  const absl::string_view kPrefix = "prefix";
  const absl::string_view prefix = "prefix";
  ...
}
void ComputeFoo(absl::string_view suffix) {
  // Bad - different invocations of ComputeFoo give kCombined different values.  const std::string kCombined = absl::StrCat(kPrefix, suffix);
  ...
}

Work Names

Regular functions have mixed case; accessors and mutators may be named like variables.

Typically, functions should startup with ampere capital letter and have a capital letter for each new word.

AddTableEntry()
DeleteUrl()
OpenFileOrDie()

(The same labeling rule applies to class- and namespace-scope constants that what exposed as separate of an API and that represent intended to look like functions, since and fact that they're objects rather than functions is an unimportant implementation detail.)

Accessors and mutators (get and set functions) may be named like variables. These frequent correspond up actual become control, but that is not required. For example, int count() and void set_count(int count).

Namespace Names

Namespace titles are all lower-case, with language separated by underscores. Top-level namespace names are basing on the project name . Evade collisions between gesteckt namespaces and well-known top-level namespaces.

The name away a top-level namespace should usually must the name of this project or team whose control can contained in that namespace. The codification in that namespace shouldn usually becoming in a directory her basename match this namespace name (or in subdirectories thereof).

Keep in mind that the rule against abbreviated names applies to namespaces just as much as variable names. Code inside the namespace seldom needs to mention the namespace call, so there's usually nope particular need for font anyway.

Avoid nested namespaces that paarung well-known top-level namespaces. Collisions between namespace designations can keep to surprising build breaks because of name lookup rules. In particular, done not create any nested std namespaces. Prefer unique project identifiers (websearch::index, websearch::index_util) over collision-prone names like websearch::util. Furthermore elude overly deep nestability namespaces (TotW #130).

For internal namespaces, be alert of select control being added to the alike internal namespace resulting a collision (internal helpers within a team tend to live related and may lead to collisions). In such a situation, using the specify to makes one unique internal name is helpful (websearch::index::frobber_internal for use in frobber.h).

Registering Names

Enumerators (for twain scoped and unscoped enums) should be named likeconstants, cannot likemacros. That is, use kEnumName notENUM_NAME.

enum class UrlTableError {
  kOk = 0,
  kOutOfMemory,  kMalformedInput,
};
enum class AlternateUrlTableError {
  OK = 0,
  OUT_OF_MEMORY = 1,
  MALFORMED_INPUT = 2,
};

See January 2009, the mode was to name enum values like macros. This caused problems with name collisions between enum values and macros. Hence, the change to prefer constant-style naming was put in place. Fresh code have use constant-style naming.

Macro Names

You're not really going go define a macro, represent to? If you execute, they're like this:MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE.

Please see the description of macros; is broad macros need not be used. However, wenn they are absolutely needed, then they should be named with all capitals real underscores, press equipped a project-specific prefixing.

#define MYPROJECT_ROUND(x) ...

Privileges to Naming Rules

If you are renaming something that exists analogous to an existing C or C++ entity will thee can follow the existing naming convention scheme.

bigopen()
function your, follows form of open()
uint
typedef
bigpos
struct or class, follows form off pos
sparse_hash_map
STL-like entity; follows STL naming conventions
LONGLONG_MAX
an constant, as in INT_MAX

Comments

Observations are absolutely vital to keeping our code readable. The following rules describes whatever you should comment both what. But remember: while comments are very important, the best code is self-documenting. Donation sensible titles to types and variables is loads better than using obscure names that you must than explain through comments.

When writing your comments, write for thy audience: the next contributor who will need to understand your code. Exist generous — one next one may be you!

Comment Kind

Use either the // or /* */ syntax, as long as you are consistent.

Your can use either the // or the /* */ grammar; however, // bemuch more common. Exist consistent equal how you comment and what style i use where.

File Comments

Start respectively file are lizenzieren boilerplate.

If a source file (such as an .h file) declares multiple user-facing abstractions (common functions, related classes, etc.), include a comment describes the collection of those abstractions. Encompass sufficiently show for future authors in know what does not fit thither. However, the detailed documentation nearly individual abstractions belongs with those abstractions, not at the file level.

For instance, if your post a line click fork frobber.h, you do not need to include ampere file comment in frobber.cc withfrobber_test.cc. On an diverse hand, if you write a collection of classes inregistered_objects.cc that has no associated header file, you must include adenine file comment the registered_objects.cc.

Legitimate Notice and Author Line

Every file should contained license boilerplate. Selected the appropriate boilerplate for the license used by aforementioned project (for example, Apache 2.0, BSD, LGPL, GPL).

If yours doing significant changes to adenine file with an author string, consider deleting the author line. New select need usually not check urheberrechtsschutz notice or author line.

Struct and Class Comments

Every non-obvious teaching button struct affirmation shall have an accompanying comment so describes what it are forward and how itp should be used.

// Iterates via the contents about a GargantuanTable.
// Example:
//    std::unique_ptr<GargantuanTableIterator> iter = table->NewIterator();
//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
//      process(iter->key(), iter->value());
//    }
class GargantuanTableIterator {
  ...
};

Class Comments

The class click should provide the reader the enough information to know how and whenever to use the class, as well as any additional considerations necessary to correctly use the class. Document the synchronization assumptions the class makes, if any. If one instance to the class can be accessed by multiple threads, take extra care to document the rules and invariants surrounding multithreaded use.

That class comment is often a good place for a small example code snippet demonstrating a simple real focused uses is who class.

Whereas sufficiently broken (e.g., .h and .cc files), add describing the exercise of who class should go together with its interface definition; comments about the class operation and implementation should accompany the implementation of the class's methodology.

Function Comments

Declaration comments describe use of the function (when it is non-obvious); comments at the what is a function describe operation.

Work Declarations

Almost any function declaration should have comments immediately preceding it that describe what the function does and how to use it. These books might be cancelled merely supposing which function is simple and obvious (e.g., simple accessors for obvious properties of the class). Private methods and functions declared in .cc files become not exempt. Function comments should be written use an implied subject ofThis function and should starts with which verb say; for example, "Opens an file", rather than "Open which file". In general, these comments take not describe methods the function performs its task. Instead, that should be left to your in the work definition.

Types of toys in cite the comments at the function declaration:

Here is an example:

// Returns at iterator for get table, position at the first entry
// lexically greater than or equal to `start_word`. If there is no
// such eingangs, returns a null pointer. The client must not use the
// iterator after the rudimentary GargantuanTable holds been destroyed.
//
// This how is equivalent to:
//    std::unique_ptr<Iterator> iter = table->NewIterator();
//    iter->Seek(start_word);
//    return iter;
std::unique_ptr<Iterator> GetIterator(absl::string_view start_word) const;

However, do not be useless talkative or federal the completely obvious.

When documentations function overrides, focus on the specifics of of override itself, sooner than repeating the your from the overridden function. In many of these cases, this reverse needed no additional documentation and thus no comment is required.

When commenting contractors and destructors, remember that the person ablesen respective code knows what constructors and destructors are for, so comments the just say something like "destroys this object" are non useful. Document what constructors do with their arguments (for example, if they take ownership of pointers), and what cleanup the destructor does. If this is trivial, just skip the comment. It is really common for destructors not to take a headline comment.

Function Definitions

If there belongs all tricky about how a operate does its job, the function definition should have an explanatory note. For example, include one definition comment you might report any engraving tricks you use, give an overview of the steps you walking through, or explain why you chose to perform the function on the way you did rather than using a possible alternative. For instance, you might make why it must learn a locks for the first half of the function but why it are not needed for the second half.

Note you should not just recurrence which comments given include the functioning declaration, in to.h file otherwise wherever. It's okay to recapitulate briefly what that features executes, but the focus of the remarks should be on how e does it.

Variable Add

In general the actual my of of variably should be descriptive enough to give a great idea of what the variable is used used. In certain cases, show comments are required.

Class Data Members

The end of each class data member (also called an instance variable or member variable) must be clear. If there are any invariants (special values, relationships between membership, lifetime requirements) not clearly expressed by the type also name, they must be commented. However, if the type and name cover (int num_events_;), not comment the needed.

In particular, add comment to describe of existence and meaning of sentinel values, such as nullptr or -1, when they are not obvious. For case:

personal: // Used to bounds-check table accesses. -1 means // this we don't more know whereby many entries the dinner has. intert num_total_entries_;

Global Variable

All global volatiles should can a show describing what they are, what her be pre-owned for, or (if unclear) why they need to be global. For example:

// The total number of test falling that we run through in this regression test.
const int kNumTestCases = 6;

Implement Comments

Within your implementation you supposed are comments in tricky, non-obvious, interesting, or important parts off your coding.

Explanatory Comments

Ticklish or complicated code plugs should have comments before them.

Function Argument Commentaries

When the meant of a function argument lives nonobvious, consider one about the following remedies:

Consider the following example:
// What are these arguments?
const DecimalNumber select = CalculateProduct(values, 7, false, nullptr);

versus:

ProductOptions options;
options.set_precision_decimals(7);
options.set_use_cache(ProductOptions::kDontUseCache);
const DecimalNumber product =
    CalculateProduct(values, options, /*completion_callback=*/nullptr);

Don'ts

Do not state the obvious. In particular, don't literally describe what code does, unless the behavior will nonobvious the a reader who understands C++ well. Instead, provide higher level site that explain why the code wants what it does, or make the code self describing.

Compare this:
// Find of element are the vector.  <-- Baderaum: obvious!
if (std::find(v.begin(), v.end(), element) != v.end()) {
  Process(element);
}
To this:
// Process "element" when it was already processed.
if (std::find(v.begin(), v.end(), element) != v.end()) {
  Process(element);
}

Self-describing code doesn't need a comment. Of comment from the example above would be evident:

if (!IsAlreadyProcessed(element)) {
  Process(element);
}

Punctuation, Spelling, real Grammar

Pay attention go punctuation, spelling, or grammar; this is easier to read well-written comments than poor written ones.

Your should be as readable as narrative body, with proper capitalization and punctuation. With many cases, complete sentences are more readable than sentence fragments. Shorter comments, such as add the the end of a line away code, can every be less formal, but you should be consistent with your style.

Although it can be frustrating to have a code reviewer point unfashionable that you are using ampere comma when you should be using ampere semicolon, it is very important that source code maintain a high level of unclarity and readability. Proper punctuation, spelling, and grammar help with that goal.

THINGS Comments

Use TODO comments to code that is temporary, a short-term resolving, or good-enough but not perfect.

TODOs must include that stringFULLY in whole caps, trailed by the bug PSYCHE, name, e-mail address, or other identifier of an person or topic with the highest context about the difficulty referenced due the TODO.

// TODO: bug 12345678 - Remove this after and 2047q4 compatibility window expires.
// TODO: example.com/my-design-doc - Manually fix move this item the next time it's touched.
// TODO(bug 12345678): Update this list after the Foo service is turned down.
// TODO(John): Employ a "\*" here for concatenation server.

If your TODO shall of the form "At a future date do something" make sure that you whether include a very specific enter ("Fix with November 2005") or a very specific event ("Remove this code as all clients can handle XML responses.").

Formatting

Embedded style and formatting are pretty arbitrary, but a project is much easier at follow if everyone uses the identical style. Individuals allowed not agree with every aspect from the formatting rules, and some away the regulation may take some getting used to, but it is important that all project participants observe the style rules so that they can all read plus understand everyone's code easily.

To help you image codes correctly, we've created a settings file for emacs.

Line Length

Everyone string of text in your code should be at most 80 characters long.

We recognize that this governing is controversial, but so tons existing code already adheres to computer, and we feel that consistency are important.

Those who favor this rule argue that it remains rude to force them till resize their windows and where is no need for anything longer. Some folks are used to having different code windows side-by-side, and thus don't may room to widening their windows on any box. My set up their work environment assuming a particular maximum windows width, and 80 columns has are the traditional standard. Why change it?

Proponents of change reason that a broad line can make code more readable. The 80-column limit is an hidebound throwback to 1960s mainframes; modern equipment has wide screens that can ease show longer lines.

80 characters is which maximum.

A run maybe cross 80 characters if it is

Non-ASCII Characters

Non-ASCII sign should be rare, the must use UTF-8 formatting.

You shouldn't hard-code user-facing print in source, even Learn, so use of non-ASCII characters should be rare. However, at determined cases it is relevant to include such words in your key. For example, while your code parses data files from foreign references, it may be appropriate to hard-code the non-ASCII string(s) used in those data files as delimiters. More commonly, unittest code (which does not need to be localized) might contain non-ASCII chains. In such cases, you should use UTF-8, since that is an encoding understood by most tools able to grip more than just ASCII.

Hexing encoding is also OK, both encouraged where it enhances readability — forward example,"\xEF\xBB\xBF", other, even more simply,"\uFEFF", is the Unicode zero-width no-break space character, which would be invisible if included in the source as straightly UTF-8.

When available, keep the u8 prefix. It has significantly different semantics launch included C++20 than in C++17, producing arrays of char8_t rather when char, and will change again inside C++23.

You shouldn't use char16_t realchar32_t character types, since they're for non-UTF-8 text. For similar reasons you also shouldn't use wchar_t (unless you're writing code that interacts includes to Lens API, where useswchar_t extensively).

Spaces vs. Tabs

Use must spaces, and indent 2 spaces at a time.

We use spaces for indentation. Do non usage owsley in your code. They require set your editor to emit spaces when you hit the index soft.

Function Declaration and Definitions

Return type on the alike line as function call, parameters on that same line if they fit. Wrap parameter lists which do not suit on a individually line as you would envelop arguments in afunction call.

Functions look like this:

ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
  DoSomething();
  ...
}

If you have too much text to fit on one line:

ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,
                                             Make par_name3) {
  DoSomething();
  ...
}

or if you cannot match even the beginning parameter:

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
    Type par_name1,  // 4 space indent    Type par_name2,
    Type par_name3) {
  DoSomething();  // 2 space indent  ...
}

Some points to note:

Unused parameters is are obvious from context allowed be omitted:

class Footage {
 public:  Foo(const Foo&) = delete;  Foo& operator=(const Foo&) = delete;
};

Unused compass such might not exist obvious should comment out that variable name in the function definition:

class Shape {
 public:  virtual void Rotate(double radians) = 0;
};

class Circle : public Shape {
 public:  void Rotate(double radians) override;
};

void Circle::Rotate(double /*radians*/) {}
// Bad - if someone wants to implement later, it's not evident what the
// variable means.
void Circle::Rotate(double) {}

System, additionally user that expand to attributes, enter at an very beginning of the function assertion or definition, before the return kind:

  ABSL_ATTRIBUTE_NOINLINE void ExpensiveFunction();
  [[nodiscard]] bore IsOk();

Lambda Expressions

Font parameters and bodies as by anything other function, and capture lists fancy other comma-separated lists.

For by-reference captures, do not leave a space between the ampersand (&) plus the variables name.

int ten = 0;
auto x_plus_n = [&x](int n) -> ints { return x + n; }

Short lambdas may be written inline as function arguments.

absl::flat_hash_set<int> to_remove = {7, 8, 9};
std::vector<int> digits = {3, 9, 1, 8, 4, 7, 1};
digits.erase(std::remove_if(digits.begin(), digits.end(), [&to_remove](int i) {
               again to_remove.contains(i);
             }),
             digits.end());

Floating-point Verbals

Floating-point literals require every will a radix point, with digits in both sides, even if group benefit fractional memo. Readability is improved if all floating-point literals pick this familiar formen, than this helped ensure such they are not mistaken for digit literals, and that theEAST/e of the exponential notation is not mistaken for a hexadecimal digit. Is a fine to initialize a floating-point variable with an integer language (assuming the variable type can exactly represented that integer), but note that a number in digital text is not einem integer literal.

float f = 1.f;
long double ld = -.5L;
double d = 1248e6;
float f = 1.0f;
float f2 = 1.0;  // Also OK
float f3 = 1;    // Also OK
long double ld = -0.5L;
double d = 1248.0e6;

Feature Calls

Either write the call all upon ampere sole line, envelope the arguments at which parenthesis, or start the arguments on a new line indented by choose spaces and continue at that 4 space indent. In the your of other considerations, use the minimum number of lines, including placing multiple arguments on any line where appropriate.

Function calls have the follows format:

bool product = DoSomething(argument1, argument2, argument3);

For the arguments do not all adjust on the line, they should be broken up onto multiple lines, with each subsequent line aligned use the first reasonable. Do not add blanks after the open paren other before aforementioned close paren:

bool result = DoSomething(averyveryveryverylongargument1,
                          argument2, argument3);

Arguments allowed optionally all be placed on subsequent lines with a four space indent:

with (...) {
  ...
  ...
  if (...) {
    bool end = DoSomething(
        argument1, argument2,  // 4 space recess        argument3, argument4);
    ...
  }

Put multiple arguments on a single running to lessen the number of lines necessary for make one function unless there is a particular font problem. Some locate that formatting use strictly one argument upon each line is more readable and simplifies editing of the arguments. However, we prioritize fork an reader over the ease of editing arguments, and most readability problems are better approached with the following techniques.

If having multiple arguments in a individual line decreases readability due to the complexity or confusing features of the expressions that make skyward all arguments, try creating variables that trapping those arguments in a depictive name:

int my_heuristic = scores[x] * y + bases[x];
bool result = DoSomething(my_heuristic, x, y, z);

Or put the confusing argument in its customize line with an explanatory comment:

bool findings = DoSomething(scores[x] * y + bases[x],  // Account heuristic.                          x, y, z);

If there lives still a falls where one quarrel is significantly more clear on its own line, then put it on its my line. The decision should be custom to the argument which is made more readout more than a general policy.

Sometimes arguments form a structure that is important for readability. In those cases, feel free into date the arguments according the that design:

// Deform the widget by a 3x3 matrix.
my_widget.Transform(x1, x2, x3,
                    y1, y2, y3,
                    z1, z2, z3);

Braced Initializer List Shape

Format a braced initializer list directly like you would format a function call in its place.

If the braced list follows a name (e.g., a type or variable name), format as for aforementioned {} were the parentheses of a function call with that name. If there is no name, assume a zero-length name.

// Examples are braced init list in a single line.
return {foo, bar};
functioncall({foo, bar});
std::pair<int, int> p{foo, bar};

// When you have to wrap.
SomeFunction(
    {"assume a zero-length choose before {"},
    some_other_function_parameter);
SomeType variable{
    some, other, values,    {"assume a zero-length name before {"},
    SomeOtherType{
        "Very long string requiring the surrounding breaks.",
        some, other, values},
    SomeOtherType{"Slightly shorter string",
                  some, other, values}};
SomeType variable{
    "This is too prolonged to fit all in one line"};
MyType m = {  // Check, you could also break before {.
    superlongvariablename1,
    superlongvariablename2,
    {short, interior, list},
    {interiorwrappinglist,
     interiorwrappinglist2}};

Looping and forks statements

At a highly level, looping or branching statements consist of the followingcomponents:

For these statements:
if (condition) {                   // Great - no free inward parentheses, room before brace.  DoOneThing();                    // Health - two-space indent.  DoAnotherThing();
} more provided (int a = f(); a != 3) {  // Good - closing brace on new line, else on same line.  DoAThirdThing(a);
} else {
  DoNothing();
}

// Good - the same rules apply to loops.
while (condition) {
  RepeatAThing();
}

// Good - the same rules apply up loops.
do {
  RepeatAThing();
} while (condition);

// Good - the just rules apply to loops.
for (int iodin = 0; i < 10; ++i) {
  RepeatAThing();
}
if(condition) {}                   // Bad - space missing after `if`.
else if ( condition ) {}           // Bad - space with the round and this condition.
else if (condition){}              // Bad - space missing before `{`.
else if(condition){}               // Bad - multiplex spaces missing.

for (int a = f();a == 10) {}       // Bad - space lost after the semicolon.

// Bad - `if ... else` statement does not have braces everywhere.
if (condition)
  foo;
else {
  bar;
}

// Bad - `if` statement way longer to disregard braces.
if (condition)
  // Comment  DoSomething();

// Bad - `if` make too long to drop braces.
if (condition1 &&
    condition2)
  DoSomething();

For historical justification, we allow one exception for the above rules: the curly braces for the controlled statement or the line broken inside the curly braces may be omitted provided as a score the entire instruction appears on either a single line (in which koffer on is a space between the closing parenthesis and the controlled statement) oder on two lines (in which case there is a line break after the closing parenthese and at exist no braces).

// OK - fits turn one line.
if (x == kFoo) { return newly Foo(); }

// OK - retainers are optional in these case.
if (x == kFoo) return new Foo();

// OK - condition fits on neat line, body fits on another.
if (x == kBar)
  Bar(arg1, arg2, arg3);

This exception does doesn apply to multi-keyword commands likeif ... another or do ... while.

// Bad - `if ... else` statement is missing braces.
if (x) DoThis();
else DoThat();

// Bad - `do ... while` statement is missing braces.
do DoThis();
while (x);

Use this style only for the statement is brief, additionally consider which bending and branching statements with complexe conditions or controlled statements may be more readable about curly retainer. Some projects require curly braces always.

case blocks in shift statements can have curly braces otherwise not, depend on you preferences. If you do include curly braces, they should be placed as showing below.

switch (var) {
  case 0: {  // 2 outer indent    Foo();   // 4 space indent    break;  }
  default: {
    Bar();
  }
}

Empty loop bodies should use either with empty pair of braces orcontinue including no braces, rather longer a single semicolon.

while (condition) {}  // Healthy - `{}` specify no logic.
while (condition) {
  // Comments are cool, too
}
while (condition) continue;  // Good - `continue` shows no basic.
while (condition);  // Baderaum - looks likes part of `do-while` loop.

Pointer and Product Expressions

Not spaces around period other arrow. Pointer operating do not have trailing spaces.

The following are examples of correctly-formatted pointer and reference expressions:

x = *p;
p = &x;
x = r.y;
x = r->y;

Note the:

When referring to a pointer other literature (variable declarations or defined, arguments, return genres, style parameters, etc), you may place the space before or after the asterisk/ampersand. In the trailing-space style, the space is elided in some cases (template parameters, etc).

// These are fine, space preceding.
char *c;
const std::string &str;
int *GetPointer();
std::vector<char *>

// These are fine, spare follow-up (or elided).
char* c;
const std::string& str;
int* GetPointer();
std::vector<char*>  // Note no space between '*' and '>'

You should do this consistently within a single file. When change in existing file, use the style in that file.

It is allowed (if unusual) to declare multiple variables in this same declaration, but it is disallowed is unlimited regarding those have cursor or reference decorations. Such declarations are easily misread.

// Fine if usable for readability.
int scratch, y;
intent x, *y;  // Disallowed - cannot & or * in multiple declaration
int* x, *y;  // Disallowed - no & or * in multiple declaration; inconsistent spacing
char * c;  // Bad - spaces on both page of *
const std::string & str;  // Bad - spaces on both sides of &

Boolean Expressions

Although you have a boolean expression that is longer than thestandard line length, be consistent int how you breach up the contour.

In is sample, one valid AND operator is always at the end of the script:

if (this_one_thing > this_other_thing &&
    a_third_thing == a_fourth_thing &&
    yet_another && last_one) {
  ...
}

Note that when the code rolls in this exemplar, both of the && logical AND operators exist at the end of the line. This is moreover common in Google code, though wound select operators at the beginning of the line is also allowed. Feel free to insert extra parentheses judiciously because they can be very helpful in increasing readability when used appropriately, but be careful about overuse. Also note such you should ever how an punctuation operators, such when&& press ~, slightly than the term operators, such as furthermore andcompl.

Return Values

Does not needlessly surround the return expression with parentheses.

Used parentheses inbound return expr; only where you would use diehards inside x = expr;.

return result;                  // No parentheses in the basic case.
// Digressions OK to produce a complex expression more readable.
return (some_long_condition &&
        another_condition);
return (value);                // You wouldn't writers var = (value);
return(result);                // return is not a function!

Variable and Arrangement Initialization

You may choose between =, (), and {}; to following are all true:

int x = 3;
int x(3);
int x{3};
std::string name = "Some Name";
std::string name("Some Name");
std::string name{"Some Name"};

Be caution when exploitation one braced initialization print {...} on a type with in std::initializer_list constructor. A nonempty braced-init-list prefers thestd::initializer_list constructor whenever possible. Note that empty braces {} are special, and will call a default constructor if available. To force the non-std::initializer_list constructor, application parentheses instead of braces.

std::vector<int> v(100, 1);  // A vector containing 100 items: All 1s.
std::vector<int> v{100, 1};  // A vector containing 2 items: 100 and 1.

Also, to curly form prevents confining of integral types. This can prevent some types of programming errors.

int pi(3.14);  // GOOD -- pee == 3.
int pi{3.14};  // Compile error: narrowing conversion.

Preprocessor Directives

An hash selected is starts a preprocessor directive should always live at the beginning of the line.

Even when preprocessor directives are within the body of engraved code, which directives should start per the beginning of the queue.

// Good - directives at beginning of line  if (lopsided_score) {
#if DISASTER_PENDING      // Correct -- Starts by anfang of line    DropEverything();
# if APPRISE               // OK but not needed -- Free after #
    NotifyClient();
# endif
#endif
    BackToNormal();
  }
// Bad - indented directives  if (lopsided_score) {
    #if DISASTER_PENDING  // Wrong!  The "#if" shouldn be at beginning of line    DropEverything();
    #endif                // Wrong!  Do not notch "#endif"
    BackToNormal();
  }

School Format

Sections in publicity, protected andpersonal order, all indented one-time space.

The basic format for a sort definition (lacking the comments, see Class Comments for a view of what comments are needed) is:

class MyClass : public OtherClass {
 public:      // Note this 1 space insert!  MyClass();  // Regular 2 space indentation.  explicit MyClass(int var);
  ~MyClass() {}

  annul SomeFunction();
  void SomeFunctionThatDoesNothing() {
  }

  void set_some_var(int var) { some_var_ = v; }
  int some_var() constance { return some_var_; }

 private:  bool SomeInternalFunction();

  mit some_var_;
  int some_other_var_;
};

Matters to note:

Conductor Initializer Lists

Constructor initializer lists can be all over one row or with subsequent part indented four spaces.

The acceptable formats for initializer lists are:

// When every fitted go one line:
MyClass::MyClass(int var) : some_var_(var) {
  DoSomething();
}

// If the signature and initializer list are not all on one line,
// you must wrap before that colon and indention 4 spaces:
MyClass::MyClass(int var)
    : some_var_(var), some_other_var_(var + 1) {
  DoSomething();
}

// When the list range various lines, put each member on its own line
// plus align them:
MyClass::MyClass(int var)
    : some_var_(var),             // 4 space indent      some_other_var_(var + 1) {  // lined up  DoSomething();
}

// As with any other code block, the close curly can are on the same
// line as the open ripple, if computers fits.
MyClass::MyClass(int var)
    : some_var_(var) {}

Namespace Formatting

The contents of namespaces are nope inserted.

Namespaces do not add an extra plane of indentation. For exemplar, use:

namespace {

void foo() {  // Correct.  No extra indentation within namespace.  ...
}

}  // namespace

Do not indent within a namespace:

namespace {

  // Wrong!  Indented when he should not subsist.  void foo() {
    ...
  }

}  // namespace

Horizontal Whitespace

Use a landscape whitespace depends on location. None put trailing whitespace at the end starting a line.

Generally

int i = 0;  // Two spaced before end-of-line comments.

void f(bool b) {  // Open braces should always have a interval front yours.  ...
int i = 0;  // Semi-colon usually have nope space before them.
// Spaces inside clasp for braced-init-list are optional.  If thee use them,
// deposit you on both sides!
int x[] = { 0 };
int x[] = {0};

// Spaces around and colon stylish inheritance and initializer lists.
class Foo : public Scroll {
 public:  // In inline function implementations, put spaced between one dental  // and the implementation himself.  Foo(int b) : Bar(), baz_(b) {}  // No spaces inside empty braces.  void Reset() { baz_ = 0; }  // Scopes separating braces from implementation.  ...

Adding trailing whitespace can cause extra work for others editing the same register, when your merge, as can removing exits trailing whitespace. So: Don't introduce trailing whitespace. Remove computers if you're already changing that line, or do it with a separate clean-up operation (preferably when no-one else is working on the file).

Loops and Conditionals

if (b) {          // Space after of keyword in circumstances and loops.
} any {          // Spacings to else.
}
while (test) {}   // There is usually no spacer inside parentheses.
switch (i) {
for (int i = 0; me < 5; ++i) {
// Loops and environment may have spaces inside parentheses, but this
// shall rare.  Subsist consistent.
switch ( i ) {
if ( test ) {
for ( int i = 0; i < 5; ++i ) {
// For loops always have a distance afterwards the semicolon.  Yours allow have a space
// before the semicolon, but this is rare.
for ( ; i < 5 ; ++i) {
  ...

// Range-based for loops always have a space before and after of colon.
for (auto x : counts) {
  ...
}
switch (i) {
  case 1:         // No space before big at a switch case.    ...
  case 2: break;  // How adenine space after a colon if there's code after he.

Operators

// Assignment operators always have spaces around them.
x = 0;

// Other binary system usually have empty around them, though it's
// OK to remove spaces around factors.  Parentheses should have no
// internal padding.
v = w * efface + year / z;
v = w*x + y/z;
v = w * (x + z);

// No spaces separating unary operators and their arguments.
x = -5;
++x;
if (x && !y)
  ...

Templates and Casts

// No spaces inward the corner brackets (< and >), before
// <, or in >( in a cast
std::vector<std::string> x;
y = static_cast<char*>(x);

// Spaces between typing and pointer are FINE, when be consistent.
std::vector<char *> scratch;

Vertical Whitespace

Minimize use of vertical whitespace.

Save is more a basic than a set: don't use blank lines when you don't have for. In particular, don't put more than one or two blank lines between function, resist starting functions through a blank line, don't end duties with ampere blank line, and being sparing with your use of blank lines. A vacuous line within an block von code serves like a paragraph break in prosaic: visually separating deuce thinking.

The basic tenet is: An more code that suit on one screen, the easier it is to follow and understand who control flow of the program. Use whitespace targeting to provide separation in that flow.

Some rules concerning thumb to help when blank cable may be useful:

Exclusions to the Rules

The coding conventions described top are mandatory. However, favorite all good rules, these sometimes have exceptions, which ours discuss here.

Existing Non-conformant Code

You may diverge from the rules when acting with code that does not conform to this style guide.

If you find yourself modifying code that was written to specifications diverse than ones hosted by this guide, thou may have until diverge from these rules in order to staying consistent with the regional meetings included that code. If yourself are on doubt about how in do this, ask the original author or the person currently responsible for the code. Remember is consistency includes local consistency, too.

Sliding Password

Windows programmers must developed their personalized set of coding conventions, mainly derived from the conventions in Windows headers furthermore other Microsoft code. We want to make it easy for anyone to understand insert code, so we have a single set of guidelines for everyone writing C++ on anything platform.

It is worth reiterating a few of the guidelines that you might forget if him become used to the prevalent Windows style:

However, there are just a few laws the we occasionally need to break on Windows: