diff --git a/cppguide.html b/cppguide.html
index b529854..eb0fe64 100644
--- a/cppguide.html
+++ b/cppguide.html
@@ -10,8 +10,6 @@
Google C++ Style Guide
-
-
Background
@@ -162,6 +160,22 @@ input.
+
C++ Version
+
+
+Currently, code should target C++11, i.e., should not use C++14 or
+C++17 features. The C++ version targeted by this guide will advance
+(aggressively) over time.
+
+
+Code should avoid features that have been removed from
+the latest language version (currently C++17), as well as the rare
+cases where code has a different meaning in that latest version.
+Use of some C++ features is restricted or disallowed. Do not use
+non-standard extensions.
+
+
+
In general, every .cc
file should have an
@@ -972,10 +986,12 @@ dynamic initialization, and reviewed very carefully.
By contrast, the following initializations are problematic:
-
time_t time(time_t*); // not constexpr!
+// 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
@@ -1514,6 +1530,7 @@ functors and traits.
+
Inheritance
@@ -1522,16 +1539,14 @@ When using inheritance, make it public
.
-
When a sub-class
inherits from a base class, it includes the definitions
-of all the data and operations that the parent base class
-defines. In practice, inheritance is used in two major
-ways in C++: implementation inheritance, in which actual
-code is inherited by the child, and
-interface inheritance, in which
-only method names are inherited.
+of all the data and operations that the base class
+defines. "Interface inheritance" is inheritance from a
+pure abstract base class (one with no state or defined
+methods); all other inheritance is "implementation
+inheritance".
@@ -1553,6 +1568,14 @@ the sub-class, it can be more difficult to understand an
implementation. The sub-class cannot override functions
that are not virtual, so the sub-class cannot change
implementation.
+
+
Multiple inheritance is especially problematic, because
+it often imposes a higher performance overhead (in fact,
+the performance drop from single inheritance to multiple
+inheritance can often be greater than the performance
+drop from ordinary to virtual dispatch), and because
+it risks leading to "diamond" inheritance patterns,
+which are prone to ambiguity, confusion, and outright bugs.
@@ -1585,119 +1608,9 @@ specifiers serve as documentation; if no specifier is
present, the reader has to check all ancestors of the
class in question to determine if the function or
destructor is virtual or not.
-
-
-
-
Multiple Inheritance
-
-
-
Only very rarely is multiple implementation inheritance
-actually useful. We allow multiple inheritance only when at
-most one of the base classes has an implementation; all
-other base classes must be pure
-interface classes tagged with the
-Interface
suffix.
-
-
-
-
-
-
Multiple inheritance allows a sub-class to have more than
-one base class. We distinguish between base classes that are
-pure interfaces and those that have an
-implementation.
-
-
-
-
Multiple implementation inheritance may let you re-use
-even more code than single inheritance (see Inheritance).
-
-
-
-
Only very rarely is multiple implementation
-inheritance actually useful. When multiple implementation
-inheritance seems like the solution, you can usually find
-a different, more explicit, and cleaner solution.
-
-
-
-
Multiple inheritance is allowed only when all
-superclasses, with the possible exception of the first one,
-are pure interfaces. In order to
-ensure that they remain pure interfaces, they must end with
-the Interface
suffix.
-
-
-
-
There is an exception to
-this rule on Windows.
-
-
-
-
-
Interfaces
-
-
-
Classes that satisfy certain conditions are allowed, but
-not required, to end with an Interface
suffix.
-
-
-
-
-
-
A class is a pure interface if it meets the following
-requirements:
-
-
- - It has only public pure virtual ("
=
- 0
") methods and static methods (but see below
- for destructor).
-
- - It may not have non-static data members.
-
- - It need not have any constructors defined. If a
- constructor is provided, it must take no arguments and
- it must be protected.
-
- - If it is a subclass, it may only be derived from
- classes that satisfy these conditions and are tagged
- with the
Interface
suffix.
-
-
-
An interface class can never be directly instantiated
-because of the pure virtual method(s) it declares. To
-make sure all implementations of the interface can be
-destroyed correctly, the interface must also declare a
-virtual destructor (in an exception to the first rule,
-this should not be pure). See Stroustrup, The C++
-Programming Language, 3rd edition, section 12.4
-for details.
-
-
-
-
Tagging a class with the Interface
suffix
-lets others know that they must not add implemented
-methods or non static data members. This is particularly
-important in the case of multiple inheritance.
-Additionally, the interface concept is already
-well-understood by Java programmers.
-
-
-
-
The Interface
suffix lengthens the class
-name, which can make it harder to read and understand.
-Also, the interface property may be considered an
-implementation detail that shouldn't be exposed to
-clients.
-
-
-
-
A class may end
-with Interface
only if it meets the above
-requirements. We do not require the converse, however:
-classes that meet the above requirements are not required
-to end with Interface
.
+
Multiple inheritance is permitted, but multiple implementation
+inheritance is strongly discouraged.
@@ -1840,7 +1753,7 @@ apply to operator overloading as well.
Access Control
-
Make data members private
, unless they are
+
Make classes' data members private
, unless they are
static const
(and follow the
naming convention for constants).
@@ -1848,7 +1761,7 @@ naming convention for constants).
For technical
-reasons, we allow data members of a test fixture class to
+reasons, we allow data members of a test fixture class in a .cc file to
be protected
when using
@@ -1956,7 +1869,7 @@ the function into smaller and more manageable pieces.
Reference Arguments
-
All parameters passed by reference must be labeled
+
All parameters passed by lvalue reference must be labeled
const
.
@@ -2053,6 +1966,11 @@ std::string_view
identically-named function to take different arguments.
It may be necessary for templatized code, and it can be
convenient for Visitors.
+
Overloading based on const or ref qualification may make utility
+ code more usable, more efficient, or both.
+
+ (See TotW 148 for more.)
+
@@ -2065,15 +1983,13 @@ function.
-
You may overload a function when there are no semantic
-differences between variants, or when the differences are
-clear at the callsite.
-
-
If you are overloading a function to support variable
-number of arguments of the same type, consider making it
-take a std::vector
so that the user can use an
-initializer list
- to specify the arguments.
+
You may overload a function when there are no semantic differences
+between variants. These overloads may vary in types, qualifiers, or
+argument count. However, a reader of such a call must not need to know
+which member of the overload set is chosen, only that something
+from the set is being called. If you can document all entries in the
+overload set with a single comment in the header, that is a good sign
+that it is a well-designed overload set.
@@ -2183,7 +2099,7 @@ doubt, use overloads.
Trailing return type syntax is relatively new and it has no
- analogue in C++-like languages like C and Java, so some readers may
+ analogue in C++-like languages such as C and Java, so some readers may
find it unfamiliar.
Existing code bases have an enormous number of function
declarations that aren't going to get changed to use the new syntax,
@@ -2385,9 +2301,19 @@ you can download
Rvalue References
-
Use rvalue references only to define move constructors and move assignment
-operators, or for perfect forwarding.
-
+
Use rvalue references to:
+
+ - Define move constructors and move assignment operators.
+
+ - Define overload sets with
+ const& and && variants if you have evidence that this
+ provides meaningfully better performance than passing by value,
+ or if you're writing low-overhead generic code that needs to support
+ arbitrary types. Beware combinatorial overload sets, that is, seldom
+ overload more than one parameter.
+
+ - Support 'perfect forwarding' in generic code.
+
@@ -2399,6 +2325,11 @@ objects. The syntax is similar to traditional reference
syntax. For example,
void f(string&&
s);
declares a function whose argument is an
rvalue reference to a string.
+
+
When the token '&&' is applied to
+an unqualified template argument in a function
+parameter, special template argument deduction
+rules apply. Such a reference is called forwarding reference.
@@ -2410,15 +2341,9 @@ rvalue reference to a string.
for example, then
auto v2(std::move(v1))
will probably just result in some simple pointer
manipulation instead of copying a large amount of data.
- In some cases this can result in a major performance
+ In many cases this can result in a major performance
improvement.
-
Rvalue references make it possible to write a
- generic function wrapper that forwards its arguments to
- another function, and works whether or not its
- arguments are temporary objects. (This is sometimes called
- "perfect forwarding".)
-
Rvalue references make it possible to implement
types that are movable but not copyable, which can be
useful for types that have no sensible definition of
@@ -2428,25 +2353,45 @@ rvalue reference to a string.
std::move
is necessary to make
effective use of some standard-library types, such as
std::unique_ptr
.
+
+
Forwarding references which
+ use the rvalue reference token, make it possible to write a
+ generic function wrapper that forwards its arguments to
+ another function, and works whether or not its
+ arguments are temporary objects and/or const.
+ This is called 'perfect forwarding'.
- - Rvalue references are a relatively new feature
- (introduced as part of C++11), and not yet widely
- understood. Rules like reference collapsing, and
- automatic synthesis of move constructors, are
- complicated.
+ - Rvalue references are not yet widely
+ understood. Rules like automatic synthesis of move constructors and reference
+ collapsing (the latter refers to the special rules that apply to a T&&
+ parameter in a function template) are somewhat obscure.
+
+ - Rvalue references are often misused. Using rvalue
+ references is counter-intuitive in signatures where the argument is expected
+ to have a valid specified state after the function call, or where no move
+ operation is performed.
-
Use rvalue references only to define move constructors and move assignment
- operators (as described in Copyable and
- Movable Types) and, in conjunction with std::forward
,
-to support perfect forwarding. You may use std::move
to express
-moving a value from one object to another rather than copying it.
+
You may use rvalue references to define move constructors and move
+ assignment operators (as described in Copyable and Movable Types). See the C++ Primer for more information about
+ move semantics and std::move
.
+
+
You may use rvalue references to define pairs of overloads, one taking
+ Foo&& and the other taking const Foo&. Usually the preferred
+ solution is just to pass by value, but an overloaded pair of functions
+ sometimes yields better performance and is sometimes necessary in generic code
+ that needs to support a wide variety of types. As always: if you're writing
+ more complicated code for the sake of performance, make sure you have evidence
+ that it actually helps.
+
+
You may use forwarding references in conjunction with std::forward
,
+ to support perfect forwarding.
@@ -2957,6 +2902,7 @@ end-users. Be consistent with the code around you, and with the
codebase as a whole; if there's an established tool for
your problem, use that tool instead.
In particular,
+
logging libraries are usually a better
choice than std::cerr
or std::clog
for diagnostic output, and the libraries in
@@ -3467,9 +3413,8 @@ name (but upper case).
Use 0
for integers and 0.0
for reals.
-For pointers (address values), there is a choice between 0
,
-NULL
, and nullptr
. For projects that allow C++11
-features, use nullptr
, as this provides type-safety.
+For pointers (address values), use nullptr
, as this
+provides type-safety.
For C++03 projects, prefer NULL
to 0
. While the
values are equivalent, NULL
looks more like a pointer to the
@@ -3830,9 +3775,6 @@ few variables for a short lambda, where the set of captured
variables is obvious at a glance. Prefer not to write long or
complex lambdas with default capture by value.
-
Keep unnamed lambdas short. If a lambda body is more than
-maybe five lines long, prefer to give the lambda a name, or to
-use a named function instead of a lambda.
Specify the return type of the lambda explicitly if that will
make it more obvious to readers, as with
auto
.
@@ -4147,7 +4089,7 @@ libraries.
-
C++11 was the official standard until august 2014, and
+
C++11 was the official standard until 2014, and
is supported by most C++ compilers. It standardizes
some common C++ extensions that we use already, allows
shorthands for some operations, and has some performance
@@ -4200,10 +4142,6 @@ guide, the following C++11 features may not be used:
<fenv.h>
headers, because many
compilers do not support those features reliably.
-
Ref-qualifiers on member functions, such as void X::Foo()
- &
or void X::Foo() &&
, because of concerns
- that they're an overly obscure feature.
-
@@ -4412,9 +4350,9 @@ template parameter.
For some symbols, this style guide recommends names to start with a capital
letter and to have a capital letter for each new word (a.k.a.
"Camel Case"
-or "Pascal case"). When abbreviations appear in such names, prefer to
-capitalize the abbreviations as single words (i.e. StartRpc()
,
-not StartRPC()
).
+or "Pascal case"). When abbreviations or acronyms appear in such
+names, prefer to capitalize the abbreviations or acronyms as single words (i.e
+
StartRpc()
, not
StartRPC()
).
Template parameters should follow the naming style for their
category: type template parameters should follow the rules for
@@ -4461,10 +4399,6 @@ of files called, e.g., foo_bar.h
and
foo_bar.cc
, defining a class called
FooBar
.
-
Inline functions must be in a .h
file. If
-your inline functions are very short, they should go
-directly into your .h
file.
-
Type Names
@@ -4562,10 +4496,12 @@ versus a class.
Variables declared constexpr or const, and whose value is fixed for
the duration of the program, are named with a leading "k" followed
- by mixed case. For example:
+ by mixed case. Underscores can be used as separators in the rare cases
+ where capitalization cannot be used for separation. For example:
const int kDaysInAWeek = 7;
+const int kAndroid8_0_0 = 24; // Android 8.0.0
@@ -5018,7 +4954,7 @@ non-obvious, interesting, or important parts of your code.
Tricky or complicated code blocks should have comments
before them. Example:
-
// Divide result by two, taking into account that x
+// Divides result by two, taking into account that x
// contains the carry from the add.
for (int i = 0; i < result->size(); i++) {
x = (x << 8) + (*result)[i];
@@ -5061,7 +4997,7 @@ std::vector<string> list{
DoSomething(); /* For trailing block comments, one space is fine. */
-Function Argument Comments
+
When the meaning of a function argument is nonobvious, consider
one of the following remedies:
@@ -5309,22 +5245,23 @@ can easily show longer lines.
80 characters is the maximum.
-
Comment lines can be longer than 80
-characters if it is not feasible to split them without
-harming readability, ease of cut and paste or auto-linking
--- e.g. if a line contains an example command or a literal
-URL longer than 80 characters.
+
A line may exceed 80 characters if it is
-
A raw-string literal may have content
-that exceeds 80 characters. Except for test code, such literals
-should appear near the top of a file.
+
-
You needn't be concerned about
-header guards that exceed
-the maximum length.
@@ -6316,29 +6253,33 @@ std::vector<char *> x;
-
This is more a principle than a rule: don't use blank
-lines when you don't have to. In particular, don't put
-more than one or two blank lines between functions,
-resist starting functions with a blank line, don't end
-functions with a blank line, and be discriminating with
-your use of blank lines inside functions.
+
This is more a principle than a rule: don't use blank lines when
+you don't have to. In particular, don't put more than one or two blank
+lines between functions, resist starting functions with a blank line,
+don't end functions with a blank line, and be sparing with your use of
+blank lines. A blank line within a block of code serves like a
+paragraph break in prose: visually separating two thoughts.
-
The basic principle is: The more code that fits on one
-screen, the easier it is to follow and understand the
-control flow of the program. Of course, readability can
-suffer from code being too dense as well as too spread
-out, so use your judgement. But in general, minimize use
-of vertical whitespace.
+
The basic principle is: The more code that fits on one screen, the
+easier it is to follow and understand the control flow of the
+program. Use whitespace purposefully to provide separation in that
+flow.
Some rules of thumb to help when blank lines may be
useful:
- Blank lines at the beginning or end of a function
- very rarely help readability.
+ do not help readability.
- Blank lines inside a chain of if-else blocks may
well help readability.
+
+ - A blank line before a comment line usually helps
+ readability — the introduction of a new comment suggests
+ the start of a new thought, and the blank line makes it clear
+ that the comment goes with the following thing instead of the
+ preceding.