Update C++ style guide.

- Encourage use of the `internal` namespace to document parts of an API
  that are not public.
- Create a separate section for `switch` statements.
- Require a project-specific prefix for macros.
- Reorganize guidance for formatting conditional statements.
- Other miscellaneous wording and formatting fixes.
This commit is contained in:
Daniel Cheng 2023-03-22 14:39:28 -07:00
parent e065b55718
commit f1dbcc3382

View File

@ -174,8 +174,9 @@ input.</p>
<p>Do not use <p>Do not use
<a href="#Nonstandard_Extensions">non-standard extensions</a>.</p> <a href="#Nonstandard_Extensions">non-standard extensions</a>.</p>
<div>Consider portability to other environments <div>
before using features from C++14 and C++17 in your project. <p>Consider portability to other environments before using features
from C++14 and C++17 in your project.</p>
</div> </div>
<h2 id="Header_Files">Header Files</h2> <h2 id="Header_Files">Header Files</h2>
@ -300,7 +301,7 @@ ABSL_DECLARE_FLAG(flag_in_b);
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 <li>A forward declaration as opposed to an <code>#include</code> statement
makes it difficult for automatic tooling to discover the module makes it difficult for automatic tooling to discover the module
defining the symbol.</li> defining the symbol.</li>
@ -676,6 +677,15 @@ inline void my_inline_function() {
</pre> </pre>
</li><li>Do not use inline namespaces.</li> </li><li>Do not use inline namespaces.</li>
<li><p>Use namespaces with "internal" in the name to document parts of an API that
should not be mentioned by users of the API.
</p>
<pre class="badcode">// We shouldn't use this internal name in non-absl code.
using ::absl::container_internal::ImplementationDetail;
</pre>
</li>
</ul> </ul>
<a id="Unnamed_Namespaces_and_Static_Variables"></a> <a id="Unnamed_Namespaces_and_Static_Variables"></a>
@ -745,10 +755,10 @@ its scope.</p>
<p>Place a function's variables in the narrowest scope <p>Place a function's variables in the narrowest scope
possible, and initialize variables in the declaration.</p> possible, and initialize variables in the declaration.</p>
<p>C++ allows you to declare variables anywhere in a <p>C++ allows you to declare variables anywhere in a function.
function. We encourage you to declare them in as local a We encourage you to declare them in a scope as local as
scope as possible, and as close to the first use as possible, and as close to the first use as possible.
possible. This makes it easier for the reader to find the This makes it easier for the reader to find the
declaration and see what type the variable is and what it declaration and see what type the variable is and what it
was initialized to. In particular, initialization should was initialized to. In particular, initialization should
be used instead of declaration and assignment, e.g.,:</p> be used instead of declaration and assignment, e.g.,:</p>
@ -757,7 +767,17 @@ be used instead of declaration and assignment, e.g.,:</p>
i = f(); // Bad -- initialization separate from declaration. i = f(); // Bad -- initialization separate from declaration.
</pre> </pre>
<pre>int j = g(); // Good -- declaration has initialization. <pre>int i = f(); // Good -- declaration has initialization.
</pre>
<pre class="badcode">int jobs = NumJobs();
// More code...
f(jobs); // Bad -- declaration separate from use.
</pre>
<pre>int jobs = NumJobs();
f(jobs); // Good -- declaration immediately (or closely) followed by use.
</pre> </pre>
<pre class="badcode">std::vector&lt;int&gt; v; <pre class="badcode">std::vector&lt;int&gt; v;
@ -979,7 +999,7 @@ does not make an observable difference. For example:</p>
If you do really prefer a dynamic container from the standard library, consider using If you do really prefer a dynamic container from the standard library, consider using
a function-local static pointer, as described below a function-local static pointer, as described below
.</li> .</li>
<li>Smart pointers (<code>unique_ptr</code>, <code>shared_ptr</code>): smart <li>Smart pointers (<code>std::unique_ptr</code>, <code>std::shared_ptr</code>): smart
pointers execute cleanup during destruction and are therefore forbidden. pointers execute cleanup during destruction and are therefore forbidden.
Consider whether your use case fits into one of the other patterns described Consider whether your use case fits into one of the other patterns described
in this section. One simple solution is to use a plain pointer to a in this section. One simple solution is to use a plain pointer to a
@ -1180,8 +1200,8 @@ void Func(Foo f);
</pre> </pre>
<pre class="badcode">Func({42, 3.14}); // Error <pre class="badcode">Func({42, 3.14}); // Error
</pre> </pre>
This kind of code isn't technically an implicit conversion, but the <p>This kind of code isn't technically an implicit conversion, but the
language treats it as one as far as <code>explicit</code> is concerned. language treats it as one as far as <code>explicit</code> is concerned.</p>
<p class="pros"></p> <p class="pros"></p>
<ul> <ul>
@ -1519,7 +1539,7 @@ that <code>Bar</code> "is a kind of"
<p>Limit the use of <code>protected</code> to those <p>Limit the use of <code>protected</code> to those
member functions that might need to be accessed from member functions that might need to be accessed from
subclasses. Note that <a href="#Access_Control">data subclasses. Note that <a href="#Access_Control">data
members should be private</a>.</p> members should be <code>private</code></a>.</p>
<p>Explicitly annotate overrides of virtual functions or virtual <p>Explicitly annotate overrides of virtual functions or virtual
destructors with exactly one of an <code>override</code> or (less destructors with exactly one of an <code>override</code> or (less
@ -1629,7 +1649,7 @@ built-in operators. For example, use <code>|</code> as a
bitwise- or logical-or, not as a shell-style pipe.</p> bitwise- or logical-or, not as a shell-style pipe.</p>
<p>Define operators only on your own types. More precisely, <p>Define operators only on your own types. More precisely,
define them in the same headers, .cc files, and namespaces define them in the same headers, <code>.cc</code> files, and namespaces
as the types they operate on. That way, the operators are available as the types they operate on. That way, the operators are available
wherever the type is, minimizing the risk of multiple wherever the type is, minimizing the risk of multiple
definitions. If possible, avoid defining operators as templates, definitions. If possible, avoid defining operators as templates,
@ -1681,18 +1701,18 @@ apply to operator overloading as well.</p>
of some easy boilerplate in the form of accessors (usually <code>const</code>) if necessary.</p> of some easy boilerplate in the form of accessors (usually <code>const</code>) if necessary.</p>
<p>For technical <p>For technical
reasons, we allow data members of a test fixture class defined in a .cc file to reasons, we allow data members of a test fixture class defined in a <code>.cc</code> file to
be <code>protected</code> when using be <code>protected</code> when using
<a href="https://github.com/google/googletest">Google <a href="https://github.com/google/googletest">Google
Test</a>. Test</a>.
If a test fixture class is defined outside of the .cc file it is used in, for example in a .h file, If a test fixture class is defined outside of the <code>.cc</code> file it is used in, for example
make data members <code>private</code>.</p> in a <code>.h</code> file, make data members <code>private</code>.</p>
<h3 id="Declaration_Order">Declaration Order</h3> <h3 id="Declaration_Order">Declaration Order</h3>
<p>Group similar declarations together, placing public parts <p>Group similar declarations together, placing <code>public</code> parts
earlier.</p> earlier.</p>
<p>A class definition should usually start with a <p>A class definition should usually start with a
@ -1708,6 +1728,8 @@ following order:</p>
<li>Types and type aliases (<code>typedef</code>, <code>using</code>, <li>Types and type aliases (<code>typedef</code>, <code>using</code>,
<code>enum</code>, nested structs and classes, and <code>friend</code> types)</li> <code>enum</code>, nested structs and classes, and <code>friend</code> types)</li>
<li>(Optionally, for structs only) non-<code>static</code> data members</li>
<li>Static constants</li> <li>Static constants</li>
<li>Factory functions</li> <li>Factory functions</li>
@ -1721,7 +1743,7 @@ following order:</p>
functions, and <code>friend</code> functions) functions, and <code>friend</code> functions)
</li> </li>
<li>Data members (static and non-static)</li> <li>All other data members (static and non-static)</li>
</ol> </ol>
<p>Do not put large method definitions inline in the <p>Do not put large method definitions inline in the
@ -1812,8 +1834,9 @@ which overload is being called.</p>
<p>You may write a function that takes a <code>const <p>You may write a function that takes a <code>const
std::string&amp;</code> and overload it with another that std::string&amp;</code> and overload it with another that
takes <code>const char*</code>. However, in this case consider takes <code>const char*</code>. However, in this case consider
std::string_view <code>std::string_view
instead.</p> </code>
instead.</p>
<pre>class MyClass { <pre>class MyClass {
public: public:
@ -1827,7 +1850,7 @@ std::string_view
identically-named function to take different arguments. identically-named function to take different arguments.
It may be necessary for templatized code, and it can be It may be necessary for templatized code, and it can be
convenient for Visitors.</p> convenient for Visitors.</p>
<p>Overloading based on const or ref qualification may make utility <p>Overloading based on <code>const</code> or ref qualification may make utility
code more usable, more efficient, or both. code more usable, more efficient, or both.
(See <a href="http://abseil.io/tips/148">TotW 148</a> for more.) (See <a href="http://abseil.io/tips/148">TotW 148</a> for more.)
</p> </p>
@ -2030,7 +2053,7 @@ all copies, and the object is deleted when the last
bookkeeping, simplifying the code and ruling out large bookkeeping, simplifying the code and ruling out large
classes of errors.</li> classes of errors.</li>
<li>For const objects, shared ownership can be a simple <li>For <code>const</code> objects, shared ownership can be a simple
and efficient alternative to deep copying.</li> and efficient alternative to deep copying.</li>
</ul> </ul>
@ -2133,12 +2156,12 @@ are a type of reference that can only bind to temporary
objects. The syntax is similar to traditional reference objects. The syntax is similar to traditional reference
syntax. For example, <code>void f(std::string&amp;&amp; syntax. For example, <code>void f(std::string&amp;&amp;
s);</code> declares a function whose argument is an s);</code> declares a function whose argument is an
rvalue reference to a std::string.</p> rvalue reference to a <code>std::string</code>.</p>
<p id="Forwarding_references"> When the token '&amp;&amp;' is applied to <p id="Forwarding_references"> When the token '&amp;&amp;' is applied to
an unqualified template argument in a function an unqualified template argument in a function
parameter, special template argument deduction parameter, special template argument deduction
rules apply. Such a reference is called forwarding reference.</p> rules apply. Such a reference is called a forwarding reference.</p>
<p class="pros"></p> <p class="pros"></p>
<ul> <ul>
@ -2227,7 +2250,7 @@ make a unittest class a friend of the class it tests.</p>
<p>Friends extend, but do not break, the encapsulation <p>Friends extend, but do not break, the encapsulation
boundary of a class. In some cases this is better than boundary of a class. In some cases this is better than
making a member public when you want to give only one making a member <code>public</code> when you want to give only one
other class access to it. However, most classes should other class access to it. However, most classes should
interact with other classes solely through their public interact with other classes solely through their public
members.</p> members.</p>
@ -2533,8 +2556,8 @@ like <code>static_cast&lt;float&gt;(double_value)</code>, or brace
initialization for conversion of arithmetic types like initialization for conversion of arithmetic types like
<code>int64_t y = int64_t{1} &lt;&lt; 42</code>. Do not use <code>int64_t y = int64_t{1} &lt;&lt; 42</code>. Do not use
cast formats like <code>(int)x</code> unless the cast is to cast formats like <code>(int)x</code> unless the cast is to
<code>void</code>. You may use cast formats like `T(x)` only when <code>void</code>. You may use cast formats like <code>T(x)</code> only when
`T` is a class type.</p> <code>T</code> is a class type.</p>
<p class="definition"></p> <p class="definition"></p>
<p> C++ introduced a <p> C++ introduced a
@ -2797,7 +2820,7 @@ many other contexts as well. In particular:</p>
</li><li>Declare methods to be <code>const</code> unless they </li><li>Declare methods to be <code>const</code> unless they
alter the logical state of the object (or enable the user to modify alter the logical state of the object (or enable the user to modify
that state, e.g., by returning a non-const reference, but that's that state, e.g., by returning a non-<code>const</code> reference, but that's
rare), or they can't safely be invoked concurrently.</li> rare), or they can't safely be invoked concurrently.</li>
</ul> </ul>
@ -2850,9 +2873,9 @@ types; and definition of constants with function
calls.</p> calls.</p>
<p class="cons"></p> <p class="cons"></p>
<p>Prematurely marking something as constexpr may cause <p>Prematurely marking something as <code>constexpr</code> may cause
migration problems if later on it has to be downgraded. migration problems if later on it has to be downgraded.
Current restrictions on what is allowed in constexpr Current restrictions on what is allowed in <code>constexpr</code>
functions and constructors may invite obscure workarounds functions and constructors may invite obscure workarounds
in these definitions.</p> in these definitions.</p>
@ -2869,23 +2892,24 @@ enable their use with <code>constexpr</code>. Do not use
<p>Of the built-in C++ integer types, the only one used <p>Of the built-in C++ integer types, the only one used
is is
<code>int</code>. If a program needs a variable of a <code>int</code>. If a program needs an integer type of a
different size, use a precise-width integer type from different size, use an exact-width integer type from
<code>&lt;cstdint&gt;</code>, such as <code>&lt;cstdint&gt;</code>, such as
<code>int16_t</code>. If your variable represents a <code>int16_t</code>. If you have a
value that could ever be greater than or equal to 2^31 value that could ever be greater than or equal to 2^31,
(2GiB), use a 64-bit type such as <code>int64_t</code>. use a 64-bit type such as <code>int64_t</code>.
Keep in mind that even if your value won't ever be too large Keep in mind that even if your value won't ever be too large
for an <code>int</code>, it may be used in intermediate for an <code>int</code>, it may be used in intermediate
calculations which may require a larger type. When in doubt, calculations which may require a larger type. When in doubt,
choose a larger type.</p> choose a larger type.</p>
<p class="definition"></p> <p class="definition"></p>
<p> C++ does not precisely specify the sizes of integer types <p>C++ does not specify exact sizes for the integer types
like <code>int</code>. Typically people assume like <code>int</code>. Common sizes on contemporary architectures are
that <code>short</code> is 16 bits, 16 bits for <code>short</code>, 32 bits for <code>int</code>, 32 or 64
<code>int</code> is 32 bits, <code>long</code> is 32 bits bits for <code>long</code>, and 64 bits for <code>long long</code>,
and <code>long long</code> is 64 bits.</p> but different platforms make different choices, in particular
for <code>long</code>.</p>
<p class="pros"></p> <p class="pros"></p>
<p>Uniformity of declaration.</p> <p>Uniformity of declaration.</p>
@ -2902,9 +2926,9 @@ like <code>int16_t</code>, <code>uint32_t</code>,
<code>int64_t</code>, etc. You should always use <code>int64_t</code>, etc. You should always use
those in preference to <code>short</code>, <code>unsigned those in preference to <code>short</code>, <code>unsigned
long long</code> and the like, when you need a guarantee long long</code> and the like, when you need a guarantee
on the size of an integer. Of the C integer types, only on the size of an integer. Of the built-in integer types, only
<code>int</code> should be used. When appropriate, you <code>int</code> should be used. When appropriate, you
are welcome to use standard types like are welcome to use standard type aliases like
<code>size_t</code> and <code>ptrdiff_t</code>.</p> <code>size_t</code> and <code>ptrdiff_t</code>.</p>
<p>We use <code>int</code> very often, for integers we <p>We use <code>int</code> very often, for integers we
@ -3308,14 +3332,14 @@ auto i = y.Find(key);
<p>For local variables, you can use type deduction to make the code clearer <p>For local variables, you can use type deduction to make the code clearer
by eliminating type information that is obvious or irrelevant, so that by eliminating type information that is obvious or irrelevant, so that
the reader can focus on the meaningful parts of the code:</p> the reader can focus on the meaningful parts of the code:</p>
<pre class="neutralcode">std::unique_ptr&lt;WidgetWithBellsAndWhistles&gt; widget_ptr = <pre class="neutralcode">std::unique_ptr&lt;WidgetWithBellsAndWhistles&gt; widget =
std::make_unique&lt;WidgetWithBellsAndWhistles&gt;(arg1, arg2); std::make_unique&lt;WidgetWithBellsAndWhistles&gt;(arg1, arg2);
absl::flat_hash_map&lt;std::string, absl::flat_hash_map&lt;std::string,
std::unique_ptr&lt;WidgetWithBellsAndWhistles&gt;&gt;::const_iterator std::unique_ptr&lt;WidgetWithBellsAndWhistles&gt;&gt;::const_iterator
it = my_map_.find(key); it = my_map_.find(key);
std::array&lt;int, 6&gt; numbers = {4, 8, 15, 16, 23, 42};</pre> std::array&lt;int, 6&gt; numbers = {4, 8, 15, 16, 23, 42};</pre>
<pre class="goodcode">auto widget_ptr = std::make_unique&lt;WidgetWithBellsAndWhistles&gt;(arg1, arg2); <pre class="goodcode">auto widget = std::make_unique&lt;WidgetWithBellsAndWhistles&gt;(arg1, arg2);
auto it = my_map_.find(key); auto it = my_map_.find(key);
std::array numbers = {4, 8, 15, 16, 23, 42};</pre> std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
@ -3795,7 +3819,7 @@ Currently, the following libraries are permitted:</p>
Special Functions</a> from <code>boost/math/special_functions</code></li> Special Functions</a> from <code>boost/math/special_functions</code></li>
<li><a href="https://www.boost.org/libs/math/doc/html/root_finding.html"> <li><a href="https://www.boost.org/libs/math/doc/html/root_finding.html">
Root Finding Functions</a> from <code>boost/math/tools</code></li> Root Finding &amp; Minimization Functions</a> from <code>boost/math/tools</code></li>
<li><a href="https://www.boost.org/libs/multi_index/"> <li><a href="https://www.boost.org/libs/multi_index/">
Multi-index</a> from <code>boost/multi_index</code></li> Multi-index</a> from <code>boost/multi_index</code></li>
@ -3869,11 +3893,12 @@ guide, the following C++ features may not be used:</p>
<p class="definition"></p> <p class="definition"></p>
<p>Compilers support various extensions that are not part of standard C++. Such <p>Compilers support various extensions that are not part of standard C++. Such
extensions include GCC's <code>__attribute__</code>, intrinsic functions such extensions include GCC's <code>__attribute__</code>, intrinsic functions such
as <code>__builtin_prefetch</code>, inline assembly, <code>__COUNTER__</code>, as <code>__builtin_prefetch</code> or SIMD, <code>#pragma</code>, inline
<code>__PRETTY_FUNCTION__</code>, compound statement expressions (e.g., assembly, <code>__COUNTER__</code>, <code>__PRETTY_FUNCTION__</code>,
<code>foo = ({ int x; Bar(&amp;x); x })</code>, variable-length arrays and compound statement expressions (e.g., <code>foo = ({ int x; Bar(&amp;x); x
<code>alloca()</code>, and the "<a href="https://en.wikipedia.org/wiki/Elvis_operator">Elvis Operator</a>" })</code>, variable-length arrays and <code>alloca()</code>, and the
<code>a?:b</code>.</p> "<a href="https://en.wikipedia.org/wiki/Elvis_operator">Elvis
Operator</a>" <code>a?:b</code>.</p>
<p class="pros"></p> <p class="pros"></p>
<ul> <ul>
@ -3892,14 +3917,15 @@ guide, the following C++ features may not be used:</p>
between compilers.</li> between compilers.</li>
<li>Nonstandard extensions add to the language features that a reader must <li>Nonstandard extensions add to the language features that a reader must
know to understand the code.</li> know to understand the code.</li>
<li>Nonstandard extensions require additional work to port across architectures.</li>
</ul> </ul>
<p class="decision"></p> <p class="decision"></p>
<p>Do not use nonstandard extensions. You may use portability wrappers that <p>Do not use nonstandard extensions. You may use portability wrappers that
are implemented using nonstandard extensions, so long as those wrappers are implemented using nonstandard extensions, so long as those wrappers
are provided by a designated project-wide are provided by a designated project-wide portability
portability header.</p> header.</p>
<h3 id="Aliases">Aliases</h3> <h3 id="Aliases">Aliases</h3>
@ -3918,9 +3944,9 @@ using other_namespace::Foo;
<p>Like other declarations, aliases declared in a header file are part of that <p>Like other declarations, aliases declared in a header file are part of that
header's public API unless they're in a function definition, in the private portion of a class, header's public API unless they're in a function definition, in the private portion of a class,
or in an explicitly-marked internal namespace. Aliases in such areas or in .cc files are or in an explicitly-marked internal namespace. Aliases in such areas or in <code>.cc</code> files
implementation details (because client code can't refer to them), and are not restricted by this are implementation details (because client code can't refer to them), and are not restricted by
rule.</p> this rule.</p>
<p class="pros"></p> <p class="pros"></p>
<ul> <ul>
@ -3979,13 +4005,60 @@ typedef unordered_set&lt;DataPoint, hash&lt;DataPoint&gt;, DataPointComparator&g
} // namespace mynamespace } // namespace mynamespace
</pre> </pre>
<p>However, local convenience aliases are fine in function definitions, private sections of <p>However, local convenience aliases are fine in function definitions, <code>private</code>
classes, explicitly marked internal namespaces, and in .cc files:</p> sections of classes, explicitly marked internal namespaces, and in <code>.cc</code> files:</p>
<pre>// In a .cc file <pre>// In a .cc file
using ::foo::Bar; using ::foo::Bar;
</pre> </pre>
<h3 id="Switch_Statements">Switch Statements</h3>
<p>If not conditional on an enumerated value, switch statements should always
have a <code>default</code> case (in the case of an enumerated value, the
compiler will warn you if any values are not handled). If the default case
should never execute, treat this as an error. For example:
</p><pre>switch (var) {
case 0: {
...
break;
}
case 1: {
...
break;
}
default: {
LOG(FATAL) &lt;&lt; "Invalid value in switch statement: " &lt;&lt; var;
}
}
</pre>
<p>Fall-through from one case label to another must be annotated using the
<code>[[fallthrough]];</code> attribute. <code>[[fallthrough]];</code> should
be placed at a point of execution where a fall-through to the next case label
occurs. A common exception is consecutive case labels without intervening code,
in which case no annotation is needed.</p>
<pre>switch (x) {
case 41: // No annotation needed here.
case 43:
if (dont_be_picky) {
// Use this instead of or along with annotations in comments.
[[fallthrough]];
} else {
CloseButNoCigar();
break;
}
case 42:
DoSomethingSpecial();
[[fallthrough]];
default:
DoSomethingGeneric();
break;
}
</pre>
<h2 id="Inclusive_Language">Inclusive Language</h2> <h2 id="Inclusive_Language">Inclusive Language</h2>
<p>In all code, including naming and comments, use inclusive language <p>In all code, including naming and comments, use inclusive language
@ -4098,7 +4171,7 @@ underscores (<code>_</code>) or dashes (<code>-</code>).
Follow the convention that your Follow the convention that your
project uses. If there is no consistent project uses. If there is no consistent
local pattern to follow, prefer "_".</p> local pattern to follow, prefer "<code>_</code>".</p>
<p>Examples of acceptable file names:</p> <p>Examples of acceptable file names:</p>
@ -4202,7 +4275,7 @@ versus a class.</p>
<h3 id="Constant_Names">Constant Names</h3> <h3 id="Constant_Names">Constant Names</h3>
<p>Variables declared constexpr or const, and whose value is fixed for <p>Variables declared <code>constexpr</code> or <code>const</code>, and whose value is fixed for
the duration of the program, are named with a leading "k" followed the duration of the program, are named with a leading "k" followed
by mixed case. Underscores can be used as separators in the rare cases by mixed case. Underscores can be used as separators in the rare cases
where capitalization cannot be used for separation. For example:</p> where capitalization cannot be used for separation. For example:</p>
@ -4242,10 +4315,10 @@ 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, with words separated by underscores. <p>Namespace names are all lower-case, with words separated by underscores.
Top-level namespace names are 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.</p>
<p>The name of a top-level namespace should usually be the <p>The name of a top-level namespace should usually be the
name of the project or team whose code is contained in that name of the project or team whose code is contained in that
@ -4319,10 +4392,9 @@ define a macro</a>, are you? If you do, they're like this:
<p>Please see the <a href="#Preprocessor_Macros">description <p>Please see the <a href="#Preprocessor_Macros">description
of macros</a>; in general macros should <em>not</em> be used. of macros</a>; in general macros should <em>not</em> be used.
However, if they are absolutely needed, then they should be However, if they are absolutely needed, then they should be
named with all capitals and underscores.</p> named with all capitals and underscores, and with a project-specific prefix.</p>
<pre>#define ROUND(x) ... <pre>#define MYPROJECT_ROUND(x) ...
#define PI_ROUNDED 3.0
</pre> </pre>
<h3 id="Exceptions_to_Naming_Rules">Exceptions to Naming Rules</h3> <h3 id="Exceptions_to_Naming_Rules">Exceptions to Naming Rules</h3>
@ -4383,8 +4455,7 @@ implements, or tests exactly one abstraction that is documented by a comment
at the point of declaration, file comments are not required. All other files at the point of declaration, file comments are not required. All other files
must have file comments.</p> must have file comments.</p>
<h4>Legal Notice and Author <h4>Legal Notice and Author Line</h4>
Line</h4>
@ -4455,7 +4526,7 @@ operation.</p>
preceding it that describe what the function does and how to use preceding it that describe what the function does and how to use
it. These comments may be omitted only if the function is simple and it. These comments may be omitted only if the function is simple and
obvious (e.g., simple accessors for obvious properties of the class). obvious (e.g., simple accessors for obvious properties of the class).
Private methods and functions declared in `.cc` files are not exempt. Private methods and functions declared in <code>.cc</code> files are not exempt.
Function comments should be written with an implied subject of Function comments should be written with an implied subject of
<i>This function</i> and should start with the verb phrase; for example, <i>This function</i> and should start with the verb phrase; for example,
"Opens the file", rather than "Open the file". In general, these comments do not "Opens the file", rather than "Open the file". In general, these comments do not
@ -4652,8 +4723,8 @@ if (std::find(v.begin(), v.end(), element) != v.end()) {
} }
</pre> </pre>
Self-describing code doesn't need a comment. The comment from <p>Self-describing code doesn't need a comment. The comment from
the example above would be obvious: the example above would be obvious:</p>
<pre>if (!IsAlreadyProcessed(element)) { <pre>if (!IsAlreadyProcessed(element)) {
Process(element); Process(element);
@ -4819,19 +4890,16 @@ ASCII.</p>
<p>Hex encoding is also OK, and encouraged where it <p>Hex encoding is also OK, and encouraged where it
enhances readability — for example, enhances readability — for example,
<code>"\xEF\xBB\xBF"</code>, or, even more simply, <code>"\xEF\xBB\xBF"</code>, or, even more simply,
<code>u8"\uFEFF"</code>, is the Unicode zero-width <code>"\uFEFF"</code>, is the Unicode zero-width
no-break space character, which would be invisible if no-break space character, which would be invisible
included in the source as straight UTF-8.</p> if included in the source as straight UTF-8.</p>
<p>Use the <code>u8</code> prefix <p>When possible, avoid the <code>u8</code> prefix.
to guarantee that a string literal containing It has significantly different semantics starting in C++20
<code>\uXXXX</code> escape sequences is encoded as UTF-8. than in C++17, producing arrays of <code>char8_t</code>
Do not use it for strings containing non-ASCII characters rather than <code>char</code>.
encoded as UTF-8, because that will produce incorrect
output if the compiler does not interpret the source file
as UTF-8. </p>
<p>You shouldn't use <code>char16_t</code> and </p><p>You shouldn't use <code>char16_t</code> and
<code>char32_t</code> character types, since they're for <code>char32_t</code> character types, since they're for
non-UTF-8 text. For similar reasons you also shouldn't non-UTF-8 text. For similar reasons you also shouldn't
use <code>wchar_t</code> (unless you're writing code that use <code>wchar_t</code> (unless you're writing code that
@ -4964,15 +5032,15 @@ return type:</p>
lists like other comma-separated lists.</p> lists like other comma-separated lists.</p>
<p>For by-reference captures, do not leave a space between the <p>For by-reference captures, do not leave a space between the
ampersand (&amp;) and the variable name.</p> ampersand (<code>&amp;</code>) and the variable name.</p>
<pre>int x = 0; <pre>int x = 0;
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; to_remove = {7, 8, 9}; <pre>absl::flat_hash_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;to_remove](int i) { digits.erase(std::remove_if(digits.begin(), digits.end(), [&amp;to_remove](int i) {
return to_remove.find(i) != to_remove.end(); return to_remove.contains(i);
}), }),
digits.end()); digits.end());
</pre> </pre>
@ -5110,174 +5178,146 @@ MyType m = { // Here, you could also break before {.
interiorwrappinglist2}}; interiorwrappinglist2}};
</pre> </pre>
<h3 id="Conditionals">Conditionals</h3> <a id="Conditionals"></a>
<h3 id="Formatting_Looping_Branching">Looping and branching statements</h3>
<p>In an <code>if</code> statement, including its optional <code>else if</code> <p>At a high level, looping or branching statements consist of the following
and <code>else</code> clauses, put one space between the <code>if</code> and the <strong>components</strong>:
opening parenthesis, and between the closing parenthesis and the curly brace (if </p><ul>
any), but no spaces between the parentheses and the condition or initializer. If <li>One or more <strong>statement keywords</strong> (e.g. <code>if</code>,
the optional initializer is present, put a space or newline after the semicolon, <code>else</code>, <code>switch</code>, <code>while</code>, <code>do</code>,
but not before.</p> or <code>for</code>).</li>
<li>One <strong>condition or iteration specifier</strong>, inside
parentheses.</li>
<li>One or more <strong>controlled statements</strong>, or blocks of
controlled statements.</li>
</ul>
For these statements:
<pre class="badcode">if(condition) { // Bad - space missing after IF <ul>
if ( condition ) { // Bad - space between the parentheses and the condition <li>The components of the statement should be separated by single spaces (not
if (condition){ // Bad - space missing before { line breaks).</li>
if(condition){ // Doubly bad <li>Inside the condition or iteration specifier, put one space (or a line
break) between each semicolon and the next token, except if the token is a
closing parenthesis or another semicolon.</li>
<li>Inside the condition or iteration specifier, do not put a space after the
opening parenthesis or before the closing parenthesis.</li>
<li>Put any controlled statements inside blocks (i.e. use curly braces).</li>
<li>Inside the controlled blocks, put one line break immediately after the
opening brace, and one line break immediately before the closing brace.</li>
</ul>
if (int a = f();a == 10) { // Bad - space missing after the semicolon <pre>if (condition) { // Good - no spaces inside parentheses, space before brace.
</pre> DoOneThing(); // Good - two-space indent.
<p>Use curly braces for the controlled statements following
<code>if</code>, <code>else if</code> and <code>else</code>. Break the line
immediately after the opening brace, and immediately before the closing brace. A
subsequent <code>else</code>, if any, appears on the same line as the preceding
closing brace, separated by a space.</p>
<pre>if (condition) { // no spaces inside parentheses, space before brace
DoOneThing(); // two space indent
DoAnotherThing(); DoAnotherThing();
} else if (int a = f(); a != 3) { // closing brace on new line, else on same line } else if (int a = f(); a != 3) { // Good - closing brace on new line, else on same line.
DoAThirdThing(a); DoAThirdThing(a);
} else { } else {
DoNothing(); DoNothing();
} }
// Good - the same rules apply to loops.
while (condition) {
RepeatAThing();
}
// Good - the same rules apply to loops.
do {
RepeatAThing();
} while (condition);
// Good - the same rules apply to loops.
for (int i = 0; i &lt; 10; ++i) {
RepeatAThing();
}
</pre> </pre>
<p>For historical reasons, we allow one exception to the above rules: if an <pre class="badcode">if(condition) {} // Bad - space missing after `if`.
<code>if</code> statement has no <code>else</code> or <code>else if</code> else if ( condition ) {} // Bad - space between the parentheses and the condition.
clauses, then the curly braces for the controlled statement or the line breaks else if (condition){} // Bad - space missing before `{`.
inside the curly braces may be omitted if as a result the entire <code>if</code> else if(condition){} // Bad - multiple spaces missing.
statement appears on either a single line (in which case there is a space
between the closing parenthesis and the controlled statement) or on two lines
(in which case there is a line break after the closing parenthesis and there are
no braces). For example, the following forms are allowed under this
exception.</p>
<pre>if (x == kFoo) return new Foo(); for (int a = f();a == 10) {} // Bad - space missing after the semicolon.
if (x == kBar) // Bad - `if ... else` statement does not have braces everywhere.
return new Bar(arg1, arg2, arg3);
if (x == kQuz) { return new Quz(1, 2, 3); }
</pre>
<p>Use this style only when the statement is brief, and consider that
conditional statements with complex conditions or controlled statements may be
more readable with curly braces. Some
projects
require curly braces always.</p>
<p>Finally, these are not permitted:</p>
<pre class="badcode">// Bad - IF statement with ELSE is missing braces
if (x) DoThis();
else DoThat();
// Bad - IF statement with ELSE does not have braces everywhere
if (condition) if (condition)
foo; foo;
else { else {
bar; bar;
} }
// Bad - IF statement is too long to omit braces // Bad - `if` statement too long to omit braces.
if (condition) if (condition)
// Comment // Comment
DoSomething(); DoSomething();
// Bad - IF statement is too long to omit braces // Bad - `if` statement too long to omit braces.
if (condition1 &amp;&amp; if (condition1 &amp;&amp;
condition2) condition2)
DoSomething(); DoSomething();
</pre> </pre>
<h3 id="Loops_and_Switch_Statements">Loops and Switch Statements</h3> <p>For historical reasons, we allow one exception to the above rules: the curly
braces for the controlled statement or the line breaks inside the curly braces
may be omitted if as a result the entire statement appears on either a single
line (in which case there is a space between the closing parenthesis and the
controlled statement) or on two lines (in which case there is a line break
after the closing parenthesis and there are no braces).</p>
<p>Switch statements may use braces for blocks. Annotate <pre class="neutralcode">// OK - fits on one line.
non-trivial fall-through between cases. if (x == kFoo) { return new Foo(); }
Braces are optional for single-statement loops.
Empty loop bodies should use either empty braces or <code>continue</code>.</p>
<p><code>case</code> blocks in <code>switch</code> // OK - braces are optional in this case.
statements can have curly braces or not, depending on if (x == kFoo) return new Foo();
your preference. If you do include curly braces they
should be placed as shown below.</p>
<p>If not conditional on an enumerated value, switch // OK - condition fits on one line, body fits on another.
statements should always have a <code>default</code> case if (x == kBar)
(in the case of an enumerated value, the compiler will Bar(arg1, arg2, arg3);
warn you if any values are not handled). If the default </pre>
case should never execute, treat this as an error. For example:
</p> <p>This exception does not apply to multi-keyword statements like
<code>if ... else</code> or <code>do ... while</code>.</p>
<pre class="badcode">// Bad - `if ... else` statement is missing braces.
if (x) DoThis();
else DoThat();
// Bad - `do ... while` statement is missing braces.
do DoThis();
while (x);
</pre>
<p>Use this style only when the statement is brief, and consider that loops and
branching statements with complex conditions or controlled statements may be
more readable with curly braces. Some
projects require curly braces always.</p>
<p><code>case</code> blocks in <code>switch</code> statements can have curly
braces or not, depending on your preference. If you do include curly braces,
they should be placed as shown below.</p>
<div>
<pre>switch (var) { <pre>switch (var) {
case 0: { // 2 space indent case 0: { // 2 space indent
... // 4 space indent Foo(); // 4 space indent
break;
}
case 1: {
...
break; break;
} }
default: { default: {
assert(false); Bar();
} }
} }
</pre> </pre>
</div>
<p>Fall-through from one case label to
another must be annotated using the
<code>[[fallthrough]];</code> attribute.
<code>[[fallthrough]];</code> should be placed at a
point of execution where a fall-through to the next case
label occurs. A common exception is consecutive case
labels without intervening code, in which case no
annotation is needed.</p>
<pre>switch (x) {
case 41: // No annotation needed here.
case 43:
if (dont_be_picky) {
// Use this instead of or along with annotations in comments.
[[fallthrough]];
} else {
CloseButNoCigar();
break;
}
case 42:
DoSomethingSpecial();
[[fallthrough]];
default:
DoSomethingGeneric();
break;
}
</pre>
<p> Braces are optional for single-statement loops.</p>
<pre>for (int i = 0; i &lt; kSomeNumber; ++i)
printf("I love you\n");
for (int i = 0; i &lt; kSomeNumber; ++i) {
printf("I take it back\n");
}
</pre>
<p>Empty loop bodies should use either an empty pair of braces or <p>Empty loop bodies should use either an empty pair of braces or
<code>continue</code> with no braces, rather than a single semicolon.</p> <code>continue</code> with no braces, rather than a single semicolon.</p>
<pre>while (condition) { <pre>while (condition) {} // Good - `{}` indicates no logic.
// Repeat test until it returns false. while (condition) {
// Comments are okay, too
} }
for (int i = 0; i &lt; kSomeNumber; ++i) {} // Good - one newline is also OK. while (condition) continue; // Good - `continue` indicates no logic.
while (condition) continue; // Good - continue indicates no logic.
</pre> </pre>
<pre class="badcode">while (condition); // Bad - looks like part of do/while loop. <pre class="badcode">while (condition); // Bad - looks like part of `do-while` loop.
</pre> </pre>
<h3 id="Pointer_and_Reference_Expressions">Pointer and Reference Expressions</h3> <h3 id="Pointer_and_Reference_Expressions">Pointer and Reference Expressions</h3>
@ -5327,9 +5367,9 @@ file.
When modifying an existing file, use the style in When modifying an existing file, use the style in
that file.</p> that file.</p>
It is allowed (if unusual) to declare multiple variables in the same <p>It is allowed (if unusual) to declare multiple variables in the same
declaration, but it is disallowed if any of those have pointer or declaration, but it is disallowed if any of those have pointer or
reference decorations. Such declarations are easily misread. reference decorations. Such declarations are easily misread.</p>
<pre>// Fine if helpful for readability. <pre>// Fine if helpful for readability.
int x, y; int x, y;
</pre> </pre>