From 3919c347aa79e6529e738b1270cc24767b830a51 Mon Sep 17 00:00:00 2001
From: Daniel Cheng If a source or header file refers to a symbol defined elsewhere,
+the file should directly include a header file which properly intends
+to provide a declaration or definition of that symbol. It should not
+include header files for any other reason.
+ Do not rely on transitive inclusions. This allows people to remove
+no-longer-needed Avoid using forward declarations where possible.
-Instead, The #define Guard
+Include What You Use
+
+#include statements from their headers without
+breaking clients. This also applies to related headers
+- foo.cc should include bar.h if it uses a
+symbol from it even if foo.h
+includes bar.h.Forward Declarations
#include the headers you need.
A "forward declaration" is a declaration of a class, -function, or template without an associated definition.
+A "forward declaration" is a declaration of an entity + without an associated definition.
+// In a C++ source file: +class B; +void FuncInB(); +extern int variable_in_b; +ABSL_DECLARE_FLAG(flag_in_b); +
#include that header.#include its header file.Please see Names and Order -of Includes for rules about when to #include a header.
+Try to avoid forward declarations of entities +defined in another project.You should include all the headers that define the symbols you rely
-upon, except in the unusual case of forward
-declaration. If you rely on symbols from bar.h,
-don't count on the fact that you included foo.h which
-(currently) includes bar.h: include bar.h
-yourself, unless foo.h explicitly demonstrates its intent
-to provide you the symbols of bar.h.
For example, the includes in
google-awesome-project/src/foo/internal/fooserver.cc
@@ -563,7 +571,7 @@
Namespaces wrap the entire source file after @@ -1316,11 +1324,12 @@
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. -Explicitly declaring or deleting all four copy/move operations is permitted, -but not required. If you provide a copy or move assignment operator, you -must also provide the corresponding constructor.
+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 class may also declare move operations in order to support efficient +moves. Explicitly declaring or deleting all four copy/move operations is +permitted, but not required. If you provide a copy or move assignment operator, +you must also provide the corresponding constructor.class Copyable {
public:
@@ -1328,12 +1337,13 @@ Copyable and Movable Types
Copyable& operator=(const Copyable& other) = default;
// The implicit move operations are suppressed by the declarations above.
+ // You may explicitly declare move operations to support efficient moves.
};
class MoveOnly {
public:
- MoveOnly(MoveOnly&& other);
- MoveOnly& operator=(MoveOnly&& other);
+ MoveOnly(MoveOnly&& other) = default;
+ MoveOnly& operator=(MoveOnly&& other) = default;
// The copy operations are implicitly deleted, but you can
// spell that out explicitly if you want:
@@ -1709,12 +1719,13 @@ Inputs and Outputs
improve readability, and often provide the same or better
performance.
-Parameters are either input to the function, output from the
+
Parameters are either inputs to the function, outputs from the
function, or both. Input parameters should usually be values
-or const references,
-while required (non-nullable) output and input/output parameters should
-usually be references. Generally, use absl::optional to represent
-optional inputs, and non-const pointers to represent
+or const references, while non-optional output and
+input/output parameters should usually be references (which cannot be null).
+Generally, use absl::optional to represent optional by-value
+inputs, and use a const pointer when the non-optional form would
+have used a reference. Use non-const pointers to represent
optional outputs.
@@ -1722,7 +1733,7 @@
Inputs and Outputs
to outlive the call, because const reference parameters bind
to temporaries. Instead, find a way to eliminate the lifetime requirement
(for example, by copying the parameter), or pass it by const
-pointer and document the non-null requirement.
+pointer and document the lifetime and non-null requirements.
@@ -2394,12 +2405,12 @@ noexcept
Run-Time Type
Information (RTTI)
-Avoid using Run Time Type Information (RTTI).
+Avoid using run-time type information (RTTI).
RTTI allows a
-programmer to query the C++ class of an object at run
-time. This is done by use of typeid or
+programmer to query the C++ class of an object at
+run-time. This is done by use of typeid or
dynamic_cast.
@@ -3126,8 +3137,8 @@ sizeof
}
-
-Use type deduction only if it makes the code clearer to readers who aren't familiar with the project, or if it makes the code safer. Do not use it @@ -3300,8 +3311,7 @@
auto it = my_map_.find(key);
-if (it != my_map_.end()) {
+ if (auto it = my_map_.find(key); it != my_map_.end()) {
WidgetWithBellsAndWhistles& widget = *it->second;
// Do stuff with `widget`
}
@@ -3367,7 +3377,7 @@ Structured bindings
As with function parameter comments, this can enable tools to detect if
you get the order of the fields wrong.
-Class template argument deduction
+Class Template Argument Deduction
Use class template argument deduction only with templates that have
explicitly opted into supporting it.
@@ -3425,7 +3435,7 @@ Class template argument deduction
Uses of CTAD must also follow the general rules on
Type deduction.
-Designated initializers
+Designated Initializers
Use designated initializers only in their C++20-compliant form.
@@ -3471,7 +3481,7 @@ Designated initializers
-Lambda expressions
+Lambda Expressions
Use lambda expressions where appropriate. Prefer explicit captures
when the lambda will escape the current scope.
@@ -3625,7 +3635,7 @@ Lambda expressions
Avoid complicated template programming.
@@ -3639,7 +3649,7 @@Template metaprogramming allows extremely flexible interfaces that
are type safe and high performance. Facilities like
-Google Test,
+Google Test,
std::tuple, std::function, and
Boost.Spirit would be impossible without it.
Do not define specializations of std::hash.
As with Boost, some modern C++ extensions encourage coding practices that hamper @@ -4029,6 +4037,21 @@
In all code, including naming and comments, use inclusive language +and avoid terms that other programmers might find disrespectful or offensive +(such as "master" and "slave", "blacklist" and "whitelist", or "redline"), +even if the terms also have an ostensibly neutral meaning. +Similarly, use gender-neutral language unless you're referring +to a specific person (and using their preferred pronouns). For example, +use "they"/"them"/"their" for people of unspecified gender +(even +when singular), and "it"/"its" for software, computers, and other +things that aren't people.
+ + +The most important consistency rules are those that govern @@ -4270,8 +4293,8 @@
// Iterates over the contents of a GargantuanTable.
// Example:
-// GargantuanTableIterator* iter = table->NewIterator();
+// std::unique_ptr<GargantuanTableIterator> iter = table->NewIterator();
// for (iter->Seek("foo"); !iter->done(); iter->Next()) {
// process(iter->key(), iter->value());
// }
-// delete iter;
class GargantuanTableIterator {
...
};
@@ -4494,7 +4516,9 @@ Function Declarations
declaration:
Here is an example:
-// Returns an iterator for this table. It is the client's -// responsibility to delete the iterator when it is done with it, -// and it must not use the iterator once the GargantuanTable object -// on which the iterator was created has been deleted. -// -// The iterator is initially positioned at the beginning of the table. +// Returns an iterator for this table, positioned at the first entry +// lexically greater than or equal to `start_word`. If there is no +// such entry, returns a null pointer. The client must not use the +// iterator after the underlying GargantuanTable has been destroyed. // // This method is equivalent to: -// Iterator* iter = table->NewIterator(); -// iter->Seek(""); +// std::unique_ptr<Iterator> iter = table->NewIterator(); +// iter->Seek(start_word); // return iter; -// If you are going to immediately seek to another place in the -// returned iterator, it will be faster to use NewIterator() -// and avoid the extra seek. -Iterator* GetIterator() const; +std::unique_ptr<Iterator> GetIterator(absl::string_view start_word) const;However, do not be unnecessarily verbose or state the @@ -4699,8 +4718,7 @@
Don'ts
Compare this:// Find the element in the vector. <-- Bad: obvious! -auto iter = std::find(v.begin(), v.end(), element); -if (iter != v.end()) { +if (std::find(v.begin(), v.end(), element) != v.end()) { Process(element); }@@ -4708,8 +4726,7 @@Don'ts
To this:// Process "element" unless it was already processed. -auto iter = std::find(v.begin(), v.end(), element); -if (iter != v.end()) { +if (std::find(v.begin(), v.end(), element) != v.end()) { Process(element); }@@ -5018,10 +5035,10 @@Lambda Expressions
auto x_plus_n = [&x](int n) -> int { return x + n; }
Short lambdas may be written inline as function arguments.
-std::set<int> blacklist = {7, 8, 9};
+std::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(), [&blacklist](int i) {
- return blacklist.find(i) != blacklist.end();
+digits.erase(std::remove_if(digits.begin(), digits.end(), [&to_remove](int i) {
+ return to_remove.find(i) != to_remove.end();
}),
digits.end());
@@ -5124,8 +5141,8 @@ Function Calls
Braced Initializer List Format
-Format a braced initializer list
-exactly like you would format a function call in its place.
+Format a braced initializer list exactly 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 if the {} were the
@@ -5146,7 +5163,7 @@
Braced Initializer List Format
{"assume a zero-length name before {"},
SomeOtherType{
"Very long string requiring the surrounding breaks.",
- some, other values},
+ some, other, values},
SomeOtherType{"Slightly shorter string",
some, other, values}};
SomeType variable{
@@ -5161,10 +5178,11 @@ Braced Initializer List Format
Conditionals
-The if and else keywords belong on separate lines.
- There should be a space between the if and the open parenthesis,
- and between the close parenthesis and the curly brace (if any), but no space
- between the parentheses and the condition.
+Each of if, else, and else if
+ belong on separate lines. There should be a space between
+ the if and the open parenthesis, and between the close
+ parenthesis and the curly brace (if any), but no space between the
+ parentheses and the condition.
if (condition) { // no spaces inside parentheses
... // 2 space indent.
@@ -5219,8 +5237,9 @@ Conditionals
However, if one part of an
-if-else statement uses curly
-braces, the other part must too:
+if-else or an
+if-else if-else statement uses curly
+braces, the other part(s) must, too:
// Not allowed - curly on IF but not ELSE
if (condition) {
@@ -5236,10 +5255,12 @@ Conditionals
}
-// Curly braces around both IF and ELSE required because
+// Curly braces around IF, ELSE IF, and ELSE required because
// one of the clauses used braces.
if (condition) {
foo;
+} else if (other_condition) {
+ frob;
} else {
bar;
}
@@ -5360,8 +5381,8 @@ Pointer and Reference Expressions
* or &.
When declaring a pointer variable or argument, you may -place the asterisk adjacent to either the type or to the +
When declaring a pointer or reference variable or argument, you may +place the asterisk/ampersand adjacent to either the type or the variable name:
// These are fine, space preceding. @@ -5385,6 +5406,7 @@Pointer and Reference Expressions
int x, *y; // Disallowed - no & or * in multiple declaration +int* x, *y; // Disallowed - no & or * in multiple declaration; inconsistent spacing char * c; // Bad - spaces on both sides of * const std::string & str; // Bad - spaces on both sides of &@@ -5440,9 +5462,6 @@Return Values
Variable and Array Initialization
-Your choice of
-=,(), or -{}.You may choose between
=,(), and{}; the following are all correct: