Merge pull request #577 from zetafunction/how-does-this-work-again

Update C++ styleguide
This commit is contained in:
Titus Winters 2020-09-25 13:27:34 -04:00 committed by GitHub
commit 96f6a64d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -247,14 +247,37 @@ guard:</p>
<h3 id="Include_What_You_Use">Include What You Use</h3>
<p>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.
</p>
<p>Do not rely on transitive inclusions. This allows people to remove
no-longer-needed <code>#include</code> statements from their headers without
breaking clients. This also applies to related headers
- <code>foo.cc</code> should include <code>bar.h</code> if it uses a
symbol from it even if <code>foo.h</code>
includes <code>bar.h</code>.</p>
<h3 id="Forward_Declarations">Forward Declarations</h3> <h3 id="Forward_Declarations">Forward Declarations</h3>
<p>Avoid using forward declarations where possible. <p>Avoid using forward declarations where possible.
Instead, <code>#include</code> the headers you need.</p> Instead, <a href="#Include_What_You_Use">include the headers you need</a>.
</p>
<p class="definition"></p> <p class="definition"></p>
<p>A "forward declaration" is a declaration of a class, <p>A "forward declaration" is a declaration of an entity
function, or template without an associated definition.</p> without an associated definition.</p>
<pre>// In a C++ source file:
class B;
void FuncInB();
extern int variable_in_b;
ABSL_DECLARE_FLAG(flag_in_b);
</pre>
<p class="pros"></p> <p class="pros"></p>
<ul> <ul>
@ -274,6 +297,10 @@ function, or template without an associated definition.</p>
user code to skip necessary recompilation when headers user code to skip necessary recompilation when headers
change.</li> change.</li>
<li>A forward declaration as opposed to an #include statement
makes it difficult for automatic tooling to discover the module
defining the symbol.</li>
<li>A forward declaration may be broken by subsequent <li>A forward declaration may be broken by subsequent
changes to the library. Forward declarations of functions changes to the library. Forward declarations of functions
and templates can prevent the header owners from making and templates can prevent the header owners from making
@ -316,19 +343,8 @@ void test(D* x) { f(x); } // calls f(B*)
</ul> </ul>
<p class="decision"></p> <p class="decision"></p>
<ul> Try to avoid forward declarations of entities
<li>Try to avoid forward declarations of entities defined in another project.
defined in another project.</li>
<li>When using a function declared in a header file,
always <code>#include</code> that header.</li>
<li>When using a class template, prefer to
<code>#include</code> its header file.</li>
</ul>
<p>Please see <a href="#Names_and_Order_of_Includes">Names and Order
of Includes</a> for rules about when to #include a header.</p>
<h3 id="Inline_Functions">Inline Functions</h3> <h3 id="Inline_Functions">Inline Functions</h3>
@ -453,14 +469,6 @@ Either style is acceptable, but prefer consistency with existing code.</p>
alphabetically. Note that older code might not conform to alphabetically. Note that older code might not conform to
this rule and should be fixed when convenient.</p> this rule and should be fixed when convenient.</p>
<p>You should include all the headers that define the symbols you rely
upon, except in the unusual case of <a href="#Forward_Declarations">forward
declaration</a>. If you rely on symbols from <code>bar.h</code>,
don't count on the fact that you included <code>foo.h</code> which
(currently) includes <code>bar.h</code>: include <code>bar.h</code>
yourself, unless <code>foo.h</code> explicitly demonstrates its intent
to provide you the symbols of <code>bar.h</code>.</p>
<p>For example, the includes in <p>For example, the includes in
<code>google-awesome-project/src/foo/internal/fooserver.cc</code> <code>google-awesome-project/src/foo/internal/fooserver.cc</code>
@ -563,7 +571,7 @@ namespaces, this can add a lot of clutter.</p>
<ul> <ul>
<li>Follow the rules on <a href="#Namespace_Names">Namespace Names</a>. <li>Follow the rules on <a href="#Namespace_Names">Namespace Names</a>.
</li><li>Terminate namespaces with comments as shown in the given examples. </li><li>Terminate multi-line namespaces with comments as shown in the given examples.
</li><li> </li><li>
<p>Namespaces wrap the entire source file after <p>Namespaces wrap the entire source file after
@ -1316,11 +1324,12 @@ declaring and/or deleting the appropriate operations in the <code>public</code>
section of the declaration.</p> section of the declaration.</p>
<p>Specifically, a copyable class should explicitly declare the copy <p>Specifically, a copyable class should explicitly declare the copy
operations, a move-only class should explicitly declare the move operations, operations, a move-only class should explicitly declare the move operations, and
and a non-copyable/movable class should explicitly delete the copy operations. a non-copyable/movable class should explicitly delete the copy operations. A
Explicitly declaring or deleting all four copy/move operations is permitted, copyable class may also declare move operations in order to support efficient
but not required. If you provide a copy or move assignment operator, you moves. Explicitly declaring or deleting all four copy/move operations is
must also provide the corresponding constructor.</p> permitted, but not required. If you provide a copy or move assignment operator,
you must also provide the corresponding constructor.</p>
<pre>class Copyable { <pre>class Copyable {
public: public:
@ -1328,12 +1337,13 @@ must also provide the corresponding constructor.</p>
Copyable&amp; operator=(const Copyable&amp; other) = default; Copyable&amp; operator=(const Copyable&amp; other) = default;
// The implicit move operations are suppressed by the declarations above. // The implicit move operations are suppressed by the declarations above.
// You may explicitly declare move operations to support efficient moves.
}; };
class MoveOnly { class MoveOnly {
public: public:
MoveOnly(MoveOnly&amp;&amp; other); MoveOnly(MoveOnly&amp;&amp; other) = default;
MoveOnly&amp; operator=(MoveOnly&amp;&amp; other); MoveOnly&amp; operator=(MoveOnly&amp;&amp; other) = default;
// The copy operations are implicitly deleted, but you can // The copy operations are implicitly deleted, but you can
// spell that out explicitly if you want: // spell that out explicitly if you want:
@ -1709,12 +1719,13 @@ a return value and sometimes via output parameters (or in/out parameters).</p>
improve readability, and often provide the same or better improve readability, and often provide the same or better
performance.</p> performance.</p>
<p>Parameters are either input to the function, output from the <p>Parameters are either inputs to the function, outputs from the
function, or both. Input parameters should usually be values function, or both. Input parameters should usually be values
or <code>const</code> references, or <code>const</code> references, while non-optional output and
while required (non-nullable) output and input/output parameters should input/output parameters should usually be references (which cannot be null).
usually be references. Generally, use <code>absl::optional</code> to represent Generally, use <code>absl::optional</code> to represent optional by-value
optional inputs, and non-<code>const</code> pointers to represent inputs, and use a <code>const</code> pointer when the non-optional form would
have used a reference. Use non-<code>const</code> pointers to represent
optional outputs.</p> optional outputs.</p>
<p> <p>
@ -1722,7 +1733,7 @@ Avoid defining functions that require a <code>const</code> reference parameter
to outlive the call, because <code>const</code> reference parameters bind to outlive the call, because <code>const</code> reference parameters bind
to temporaries. Instead, find a way to eliminate the lifetime requirement to temporaries. Instead, find a way to eliminate the lifetime requirement
(for example, by copying the parameter), or pass it by <code>const</code> (for example, by copying the parameter), or pass it by <code>const</code>
pointer and document the non-null requirement. pointer and document the lifetime and non-null requirements.
</p> </p>
@ -2394,12 +2405,12 @@ functions throwing and make it unconditionally
<h3 id="Run-Time_Type_Information__RTTI_">Run-Time Type <h3 id="Run-Time_Type_Information__RTTI_">Run-Time Type
Information (RTTI)</h3> Information (RTTI)</h3>
<p>Avoid using Run Time Type Information (RTTI).</p> <p>Avoid using run-time type information (RTTI).</p>
<p class="definition"></p> <p class="definition"></p>
<p> RTTI allows a <p> RTTI allows a
programmer to query the C++ class of an object at run programmer to query the C++ class of an object at
time. This is done by use of <code>typeid</code> or run-time. This is done by use of <code>typeid</code> or
<code>dynamic_cast</code>.</p> <code>dynamic_cast</code>.</p>
<p class="pros"></p> <p class="pros"></p>
@ -3126,8 +3137,8 @@ memset(&amp;data, 0, sizeof(data));
} }
</pre> </pre>
<a name="auto"></a> <a id="auto"></a>
<h3 id="Type_deduction">Type deduction</h3> <h3 id="Type_deduction">Type Deduction (including auto)</h3>
<p>Use type deduction only if it makes the code clearer to readers who aren't <p>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 familiar with the project, or if it makes the code safer. Do not use it
@ -3300,8 +3311,7 @@ std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
key type aren't relevant, but the type of the values is probably useful. key type aren't relevant, but the type of the values is probably useful.
In such situations, it's often possible to define local variables with In such situations, it's often possible to define local variables with
explicit types that convey the relevant information: explicit types that convey the relevant information:
</p><pre class="goodcode">auto it = my_map_.find(key); </p><pre class="goodcode">if (auto it = my_map_.find(key); it != my_map_.end()) {
if (it != my_map_.end()) {
WidgetWithBellsAndWhistles&amp; widget = *it-&gt;second; WidgetWithBellsAndWhistles&amp; widget = *it-&gt;second;
// Do stuff with `widget` // Do stuff with `widget`
}</pre> }</pre>
@ -3367,7 +3377,7 @@ if (it != my_map_.end()) {
As with function parameter comments, this can enable tools to detect if As with function parameter comments, this can enable tools to detect if
you get the order of the fields wrong. you get the order of the fields wrong.
<h3 id="CTAD">Class template argument deduction</h3> <h3 id="CTAD">Class Template Argument Deduction</h3>
<p>Use class template argument deduction only with templates that have <p>Use class template argument deduction only with templates that have
explicitly opted into supporting it.</p> explicitly opted into supporting it.</p>
@ -3425,7 +3435,7 @@ array(T, U...) -&gt; std::array&lt;T, 1 + sizeof...(U)&gt;;
<p>Uses of CTAD must also follow the general rules on <p>Uses of CTAD must also follow the general rules on
<a href="#Type_deduction">Type deduction</a>.</p> <a href="#Type_deduction">Type deduction</a>.</p>
<h3 id="Designated_initializers">Designated initializers</h3> <h3 id="Designated_initializers">Designated Initializers</h3>
<p>Use designated initializers only in their C++20-compliant form.</p> <p>Use designated initializers only in their C++20-compliant form.</p>
@ -3471,7 +3481,7 @@ fields appear in the struct definition.</p>
<h3 id="Lambda_expressions">Lambda expressions</h3> <h3 id="Lambda_expressions">Lambda Expressions</h3>
<p>Use lambda expressions where appropriate. Prefer explicit captures <p>Use lambda expressions where appropriate. Prefer explicit captures
when the lambda will escape the current scope.</p> when the lambda will escape the current scope.</p>
@ -3625,7 +3635,7 @@ complex lambdas with default capture by value.
</ul> </ul>
<h3 id="Template_metaprogramming">Template metaprogramming</h3> <h3 id="Template_metaprogramming">Template Metaprogramming</h3>
<p>Avoid complicated template programming.</p> <p>Avoid complicated template programming.</p>
@ -3639,7 +3649,7 @@ computation in the type domain.</p>
<p>Template metaprogramming allows extremely flexible interfaces that <p>Template metaprogramming allows extremely flexible interfaces that
are type safe and high performance. Facilities like are type safe and high performance. Facilities like
<a href="https://code.google.com/p/googletest/">Google Test</a>, <a href="https://github.com/google/googletest">Google Test</a>,
<code>std::tuple</code>, <code>std::function</code>, and <code>std::tuple</code>, <code>std::function</code>, and
Boost.Spirit would be impossible without it.</p> Boost.Spirit would be impossible without it.</p>
@ -3795,8 +3805,6 @@ features to the list, so this list may be expanded in
the future.</p> the future.</p>
</div> </div>
<h3 id="std_hash">std::hash</h3> <h3 id="std_hash">std::hash</h3>
<p>Do not define specializations of <code>std::hash</code>.</p> <p>Do not define specializations of <code>std::hash</code>.</p>
@ -3870,7 +3878,7 @@ using a new customization mechanism that doesn't have the drawbacks of
<h3 id="Other_Features"><a name="C++11">Other C++ Features</a></h3> <h3 id="Other_Features"><a id="C++11">Other C++ Features</a></h3>
<p>As with <a href="#Boost">Boost</a>, some modern C++ <p>As with <a href="#Boost">Boost</a>, some modern C++
extensions encourage coding practices that hamper extensions encourage coding practices that hamper
@ -4029,6 +4037,21 @@ typedef unordered_set&lt;DataPoint, hash&lt;DataPoint&gt;, DataPointComparator&g
using ::foo::Bar; using ::foo::Bar;
</pre> </pre>
<h2 id="Inclusive_Language">Inclusive Language</h2>
<p>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
(<a href="https://apastyle.apa.org/style-grammar-guidelines/grammar/singular-they">even
when singular</a>), and "it"/"its" for software, computers, and other
things that aren't people.</p>
<h2 id="Naming">Naming</h2> <h2 id="Naming">Naming</h2>
<p>The most important consistency rules are those that govern <p>The most important consistency rules are those that govern
@ -4270,8 +4293,8 @@ set_count(int count)</code>.</p>
<h3 id="Namespace_Names">Namespace Names</h3> <h3 id="Namespace_Names">Namespace Names</h3>
Namespace names are all lower-case. Top-level namespace names are Namespace names are all lower-case, with words separated by underscores.
based on the project name Top-level namespace names are based on the project name
. Avoid collisions . Avoid collisions
between nested namespaces and well-known top-level namespaces. between nested namespaces and well-known top-level namespaces.
@ -4446,11 +4469,10 @@ be used.</p>
<pre>// Iterates over the contents of a GargantuanTable. <pre>// Iterates over the contents of a GargantuanTable.
// Example: // Example:
// GargantuanTableIterator* iter = table-&gt;NewIterator(); // std::unique_ptr&lt;GargantuanTableIterator&gt; iter = table-&gt;NewIterator();
// for (iter-&gt;Seek("foo"); !iter-&gt;done(); iter-&gt;Next()) { // for (iter-&gt;Seek("foo"); !iter-&gt;done(); iter-&gt;Next()) {
// process(iter-&gt;key(), iter-&gt;value()); // process(iter-&gt;key(), iter-&gt;value());
// } // }
// delete iter;
class GargantuanTableIterator { class GargantuanTableIterator {
... ...
}; };
@ -4494,7 +4516,9 @@ left to comments in the function definition.</p>
declaration:</p> declaration:</p>
<ul> <ul>
<li>What the inputs and outputs are.</li> <li>What the inputs and outputs are. If function argument names
are provided in `backticks`, then code-indexing
tools may be able to present the documentation better.</li>
<li>For class member functions: whether the object <li>For class member functions: whether the object
remembers reference arguments beyond the duration of remembers reference arguments beyond the duration of
@ -4516,21 +4540,16 @@ declaration:</p>
<p>Here is an example:</p> <p>Here is an example:</p>
<pre>// Returns an iterator for this table. It is the client's <pre>// Returns an iterator for this table, positioned at the first entry
// responsibility to delete the iterator when it is done with it, // lexically greater than or equal to `start_word`. If there is no
// and it must not use the iterator once the GargantuanTable object // such entry, returns a null pointer. The client must not use the
// on which the iterator was created has been deleted. // iterator after the underlying GargantuanTable has been destroyed.
//
// The iterator is initially positioned at the beginning of the table.
// //
// This method is equivalent to: // This method is equivalent to:
// Iterator* iter = table-&gt;NewIterator(); // std::unique_ptr&lt;Iterator&gt; iter = table-&gt;NewIterator();
// iter-&gt;Seek(""); // iter-&gt;Seek(start_word);
// return iter; // return iter;
// If you are going to immediately seek to another place in the std::unique_ptr&lt;Iterator&gt; GetIterator(absl::string_view start_word) const;
// returned iterator, it will be faster to use NewIterator()
// and avoid the extra seek.
Iterator* GetIterator() const;
</pre> </pre>
<p>However, do not be unnecessarily verbose or state the <p>However, do not be unnecessarily verbose or state the
@ -4699,8 +4718,7 @@ the code does what it does, or make the code self describing.</p>
Compare this: Compare this:
<pre class="badcode">// Find the element in the vector. &lt;-- Bad: obvious! <pre class="badcode">// Find the element in the vector. &lt;-- Bad: obvious!
auto iter = std::find(v.begin(), v.end(), element); if (std::find(v.begin(), v.end(), element) != v.end()) {
if (iter != v.end()) {
Process(element); Process(element);
} }
</pre> </pre>
@ -4708,8 +4726,7 @@ if (iter != v.end()) {
To this: To this:
<pre>// Process "element" unless it was already processed. <pre>// Process "element" unless it was already processed.
auto iter = std::find(v.begin(), v.end(), element); if (std::find(v.begin(), v.end(), element) != v.end()) {
if (iter != v.end()) {
Process(element); Process(element);
} }
</pre> </pre>
@ -5018,10 +5035,10 @@ ampersand (&amp;) and the variable name.</p>
auto x_plus_n = [&amp;x](int n) -&gt; int { return x + n; } auto x_plus_n = [&amp;x](int n) -&gt; int { return x + n; }
</pre> </pre>
<p>Short lambdas may be written inline as function arguments.</p> <p>Short lambdas may be written inline as function arguments.</p>
<pre>std::set&lt;int&gt; blacklist = {7, 8, 9}; <pre>std::set&lt;int&gt; to_remove = {7, 8, 9};
std::vector&lt;int&gt; digits = {3, 9, 1, 8, 4, 7, 1}; std::vector&lt;int&gt; digits = {3, 9, 1, 8, 4, 7, 1};
digits.erase(std::remove_if(digits.begin(), digits.end(), [&amp;blacklist](int i) { digits.erase(std::remove_if(digits.begin(), digits.end(), [&amp;to_remove](int i) {
return blacklist.find(i) != blacklist.end(); return to_remove.find(i) != to_remove.end();
}), }),
digits.end()); digits.end());
</pre> </pre>
@ -5124,8 +5141,8 @@ my_widget.Transform(x1, x2, x3,
<h3 id="Braced_Initializer_List_Format">Braced Initializer List Format</h3> <h3 id="Braced_Initializer_List_Format">Braced Initializer List Format</h3>
<p>Format a <a href="#Braced_Initializer_List">braced initializer list</a> <p>Format a braced initializer list exactly like you would format a function
exactly like you would format a function call in its place.</p> call in its place.</p>
<p>If the braced list follows a name (e.g., a type or <p>If the braced list follows a name (e.g., a type or
variable name), format as if the <code>{}</code> were the variable name), format as if the <code>{}</code> were the
@ -5146,7 +5163,7 @@ SomeType variable{
{"assume a zero-length name before {"}, {"assume a zero-length name before {"},
SomeOtherType{ SomeOtherType{
"Very long string requiring the surrounding breaks.", "Very long string requiring the surrounding breaks.",
some, other values}, some, other, values},
SomeOtherType{"Slightly shorter string", SomeOtherType{"Slightly shorter string",
some, other, values}}; some, other, values}};
SomeType variable{ SomeType variable{
@ -5161,10 +5178,11 @@ MyType m = { // Here, you could also break before {.
<h3 id="Conditionals">Conditionals</h3> <h3 id="Conditionals">Conditionals</h3>
<p>The <code>if</code> and <code>else</code> keywords belong on separate lines. <p>Each of <code>if</code>, <code>else</code>, and <code>else if</code>
There should be a space between the <code>if</code> and the open parenthesis, belong on separate lines. There should be a space between
and between the close parenthesis and the curly brace (if any), but no space the <code>if</code> and the open parenthesis, and between the close
between the parentheses and the condition.</p> parenthesis and the curly brace (if any), but no space between the
parentheses and the condition.</p>
<pre>if (condition) { // no spaces inside parentheses <pre>if (condition) { // no spaces inside parentheses
... // 2 space indent. ... // 2 space indent.
@ -5219,8 +5237,9 @@ if (condition) {
</pre> </pre>
<p>However, if one part of an <p>However, if one part of an
<code>if</code>-<code>else</code> statement uses curly <code>if</code>-<code>else</code> or an
braces, the other part must too:</p> <code>if</code>-<code>else if</code>-<code>else</code> statement uses curly
braces, the other part(s) must, too:</p>
<pre class="badcode">// Not allowed - curly on IF but not ELSE <pre class="badcode">// Not allowed - curly on IF but not ELSE
if (condition) { if (condition) {
@ -5236,10 +5255,12 @@ else {
} }
</pre> </pre>
<pre>// Curly braces around both IF and ELSE required because <pre>// Curly braces around IF, ELSE IF, and ELSE required because
// one of the clauses used braces. // one of the clauses used braces.
if (condition) { if (condition) {
foo; foo;
} else if (other_condition) {
frob;
} else { } else {
bar; bar;
} }
@ -5360,8 +5381,8 @@ x = r-&gt;y;
<code>*</code> or <code>&amp;</code>.</li> <code>*</code> or <code>&amp;</code>.</li>
</ul> </ul>
<p>When declaring a pointer variable or argument, you may <p>When declaring a pointer or reference variable or argument, you may
place the asterisk adjacent to either the type or to the place the asterisk/ampersand adjacent to either the type or the
variable name:</p> variable name:</p>
<pre>// These are fine, space preceding. <pre>// These are fine, space preceding.
@ -5385,6 +5406,7 @@ reference decorations. Such declarations are easily misread.
int x, y; int x, y;
</pre> </pre>
<pre class="badcode">int x, *y; // Disallowed - no &amp; or * in multiple declaration <pre class="badcode">int x, *y; // Disallowed - no &amp; or * in multiple declaration
int* x, *y; // Disallowed - no &amp; or * in multiple declaration; inconsistent spacing
char * c; // Bad - spaces on both sides of * char * c; // Bad - spaces on both sides of *
const std::string &amp; str; // Bad - spaces on both sides of &amp; const std::string &amp; str; // Bad - spaces on both sides of &amp;
</pre> </pre>
@ -5440,9 +5462,6 @@ return(result); // return is not a function!
<h3 id="Variable_and_Array_Initialization">Variable and Array Initialization</h3> <h3 id="Variable_and_Array_Initialization">Variable and Array Initialization</h3>
<p>Your choice of <code>=</code>, <code>()</code>, or
<code>{}</code>.</p>
<p>You may choose between <code>=</code>, <p>You may choose between <code>=</code>,
<code>()</code>, and <code>{}</code>; the following are <code>()</code>, and <code>{}</code>; the following are
all correct:</p> all correct:</p>