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
<a href="#Nonstandard_Extensions">non-standard extensions</a>.</p>
<div>Consider portability to other environments
before using features from C++14 and C++17 in your project.
<div>
<p>Consider portability to other environments before using features
from C++14 and C++17 in your project.</p>
</div>
<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
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
defining the symbol.</li>
@ -676,6 +677,15 @@ inline void my_inline_function() {
</pre>
</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>
<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
possible, and initialize variables in the declaration.</p>
<p>C++ allows you to declare variables anywhere in a
function. We encourage you to declare them in as local a
scope as possible, and as close to the first use as
possible. This makes it easier for the reader to find the
<p>C++ allows you to declare variables anywhere in a function.
We encourage you to declare them in a scope as local as
possible, and as close to the first use as possible.
This makes it easier for the reader to find the
declaration and see what type the variable is and what it
was initialized to. In particular, initialization should
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.
</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 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
a function-local static pointer, as described below
.</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.
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
@ -1180,8 +1200,8 @@ void Func(Foo f);
</pre>
<pre class="badcode">Func({42, 3.14}); // Error
</pre>
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.
<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.</p>
<p class="pros"></p>
<ul>
@ -1519,7 +1539,7 @@ that <code>Bar</code> "is a kind of"
<p>Limit the use of <code>protected</code> to those
member functions that might need to be accessed from
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
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>
<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
wherever the type is, minimizing the risk of multiple
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>
<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
<a href="https://github.com/google/googletest">Google
Test</a>.
If a test fixture class is defined outside of the .cc file it is used in, for example in a .h file,
make data members <code>private</code>.</p>
If a test fixture class is defined outside of the <code>.cc</code> file it is used in, for example
in a <code>.h</code> file, make data members <code>private</code>.</p>
<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>
<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>,
<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>Factory functions</li>
@ -1721,7 +1743,7 @@ following order:</p>
functions, and <code>friend</code> functions)
</li>
<li>Data members (static and non-static)</li>
<li>All other data members (static and non-static)</li>
</ol>
<p>Do not put large method definitions inline in the
@ -1812,7 +1834,8 @@ which overload is being called.</p>
<p>You may write a function that takes a <code>const
std::string&amp;</code> and overload it with another that
takes <code>const char*</code>. However, in this case consider
std::string_view
<code>std::string_view
</code>
instead.</p>
<pre>class MyClass {
@ -1827,7 +1850,7 @@ std::string_view
identically-named function to take different arguments.
It may be necessary for templatized code, and it can be
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.
(See <a href="http://abseil.io/tips/148">TotW 148</a> for more.)
</p>
@ -2030,7 +2053,7 @@ all copies, and the object is deleted when the last
bookkeeping, simplifying the code and ruling out large
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>
</ul>
@ -2133,12 +2156,12 @@ are a type of reference that can only bind to temporary
objects. The syntax is similar to traditional reference
syntax. For example, <code>void f(std::string&amp;&amp;
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
an unqualified template argument in a function
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>
<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
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
interact with other classes solely through their public
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
<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
<code>void</code>. You may use cast formats like `T(x)` only when
`T` is a class type.</p>
<code>void</code>. You may use cast formats like <code>T(x)</code> only when
<code>T</code> is a class type.</p>
<p class="definition"></p>
<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
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>
</ul>
@ -2850,9 +2873,9 @@ types; and definition of constants with function
calls.</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.
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
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
is
<code>int</code>. If a program needs a variable of a
different size, use a precise-width integer type from
<code>int</code>. If a program needs an integer type of a
different size, use an exact-width integer type from
<code>&lt;cstdint&gt;</code>, such as
<code>int16_t</code>. If your variable represents a
value that could ever be greater than or equal to 2^31
(2GiB), use a 64-bit type such as <code>int64_t</code>.
<code>int16_t</code>. If you have a
value that could ever be greater than or equal to 2^31,
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
for an <code>int</code>, it may be used in intermediate
calculations which may require a larger type. When in doubt,
choose a larger type.</p>
<p class="definition"></p>
<p> C++ does not precisely specify the sizes of integer types
like <code>int</code>. Typically people assume
that <code>short</code> is 16 bits,
<code>int</code> is 32 bits, <code>long</code> is 32 bits
and <code>long long</code> is 64 bits.</p>
<p>C++ does not specify exact sizes for the integer types
like <code>int</code>. Common sizes on contemporary architectures are
16 bits for <code>short</code>, 32 bits for <code>int</code>, 32 or 64
bits for <code>long</code>, and 64 bits for <code>long long</code>,
but different platforms make different choices, in particular
for <code>long</code>.</p>
<p class="pros"></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
those in preference to <code>short</code>, <code>unsigned
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
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>
<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
by eliminating type information that is obvious or irrelevant, so that
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);
absl::flat_hash_map&lt;std::string,
std::unique_ptr&lt;WidgetWithBellsAndWhistles&gt;&gt;::const_iterator
it = my_map_.find(key);
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);
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>
<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/">
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>Compilers support various extensions that are not part of standard C++. Such
extensions include GCC's <code>__attribute__</code>, intrinsic functions such
as <code>__builtin_prefetch</code>, inline assembly, <code>__COUNTER__</code>,
<code>__PRETTY_FUNCTION__</code>, compound statement expressions (e.g.,
<code>foo = ({ int x; Bar(&amp;x); x })</code>, variable-length arrays and
<code>alloca()</code>, and the "<a href="https://en.wikipedia.org/wiki/Elvis_operator">Elvis Operator</a>"
<code>a?:b</code>.</p>
as <code>__builtin_prefetch</code> or SIMD, <code>#pragma</code>, inline
assembly, <code>__COUNTER__</code>, <code>__PRETTY_FUNCTION__</code>,
compound statement expressions (e.g., <code>foo = ({ int x; Bar(&amp;x); x
})</code>, variable-length arrays and <code>alloca()</code>, and the
"<a href="https://en.wikipedia.org/wiki/Elvis_operator">Elvis
Operator</a>" <code>a?:b</code>.</p>
<p class="pros"></p>
<ul>
@ -3892,14 +3917,15 @@ guide, the following C++ features may not be used:</p>
between compilers.</li>
<li>Nonstandard extensions add to the language features that a reader must
know to understand the code.</li>
<li>Nonstandard extensions require additional work to port across architectures.</li>
</ul>
<p class="decision"></p>
<p>Do not use nonstandard extensions. You may use portability wrappers that
are implemented using nonstandard extensions, so long as those wrappers
are provided by a designated project-wide
portability header.</p>
are provided by a designated project-wide portability
header.</p>
<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
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
implementation details (because client code can't refer to them), and are not restricted by this
rule.</p>
or in an explicitly-marked internal namespace. Aliases in such areas or in <code>.cc</code> files
are implementation details (because client code can't refer to them), and are not restricted by
this rule.</p>
<p class="pros"></p>
<ul>
@ -3979,13 +4005,60 @@ typedef unordered_set&lt;DataPoint, hash&lt;DataPoint&gt;, DataPointComparator&g
} // namespace mynamespace
</pre>
<p>However, local convenience aliases are fine in function definitions, private sections of
classes, explicitly marked internal namespaces, and in .cc files:</p>
<p>However, local convenience aliases are fine in function definitions, <code>private</code>
sections of classes, explicitly marked internal namespaces, and in <code>.cc</code> files:</p>
<pre>// In a .cc file
using ::foo::Bar;
</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>
<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
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>
@ -4202,7 +4275,7 @@ versus a class.</p>
<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
by mixed case. Underscores can be used as separators in the rare cases
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>
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
. 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
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
of macros</a>; in general macros should <em>not</em> be used.
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) ...
#define PI_ROUNDED 3.0
<pre>#define MYPROJECT_ROUND(x) ...
</pre>
<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
must have file comments.</p>
<h4>Legal Notice and Author
Line</h4>
<h4>Legal Notice and Author Line</h4>
@ -4455,7 +4526,7 @@ operation.</p>
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
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
<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
@ -4652,8 +4723,8 @@ if (std::find(v.begin(), v.end(), element) != v.end()) {
}
</pre>
Self-describing code doesn't need a comment. The comment from
the example above would be obvious:
<p>Self-describing code doesn't need a comment. The comment from
the example above would be obvious:</p>
<pre>if (!IsAlreadyProcessed(element)) {
Process(element);
@ -4819,19 +4890,16 @@ ASCII.</p>
<p>Hex encoding is also OK, and encouraged where it
enhances readability — for example,
<code>"\xEF\xBB\xBF"</code>, or, even more simply,
<code>u8"\uFEFF"</code>, is the Unicode zero-width
no-break space character, which would be invisible if
included in the source as straight UTF-8.</p>
<code>"\uFEFF"</code>, is the Unicode zero-width
no-break space character, which would be invisible
if included in the source as straight UTF-8.</p>
<p>Use the <code>u8</code> prefix
to guarantee that a string literal containing
<code>\uXXXX</code> escape sequences is encoded as UTF-8.
Do not use it for strings containing non-ASCII characters
encoded as UTF-8, because that will produce incorrect
output if the compiler does not interpret the source file
as UTF-8. </p>
<p>When possible, avoid the <code>u8</code> prefix.
It has significantly different semantics starting in C++20
than in C++17, producing arrays of <code>char8_t</code>
rather than <code>char</code>.
<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
non-UTF-8 text. For similar reasons you also shouldn't
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>
<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;
auto x_plus_n = [&amp;x](int n) -&gt; int { return x + n; }
</pre>
<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};
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());
</pre>
@ -5110,174 +5178,146 @@ MyType m = { // Here, you could also break before {.
interiorwrappinglist2}};
</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>
and <code>else</code> clauses, put one space between the <code>if</code> and the
opening parenthesis, and between the closing parenthesis and the curly brace (if
any), but no spaces between the parentheses and the condition or initializer. If
the optional initializer is present, put a space or newline after the semicolon,
but not before.</p>
<p>At a high level, looping or branching statements consist of the following
<strong>components</strong>:
</p><ul>
<li>One or more <strong>statement keywords</strong> (e.g. <code>if</code>,
<code>else</code>, <code>switch</code>, <code>while</code>, <code>do</code>,
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
if ( condition ) { // Bad - space between the parentheses and the condition
if (condition){ // Bad - space missing before {
if(condition){ // Doubly bad
<ul>
<li>The components of the statement should be separated by single spaces (not
line breaks).</li>
<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>
<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
<pre>if (condition) { // Good - no spaces inside parentheses, space before brace.
DoOneThing(); // Good - two-space indent.
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);
} else {
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>
<p>For historical reasons, we allow one exception to the above rules: if an
<code>if</code> statement has no <code>else</code> or <code>else if</code>
clauses, then the curly braces for the controlled statement or the line breaks
inside the curly braces may be omitted if as a result the entire <code>if</code>
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 class="badcode">if(condition) {} // Bad - space missing after `if`.
else if ( condition ) {} // Bad - space between the parentheses and the condition.
else if (condition){} // Bad - space missing before `{`.
else if(condition){} // Bad - multiple spaces missing.
<pre>if (x == kFoo) return new Foo();
for (int a = f();a == 10) {} // Bad - space missing after the semicolon.
if (x == kBar)
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
// Bad - `if ... else` statement does not have braces everywhere.
if (condition)
foo;
else {
bar;
}
// Bad - IF statement is too long to omit braces
// Bad - `if` statement too long to omit braces.
if (condition)
// Comment
DoSomething();
// Bad - IF statement is too long to omit braces
// Bad - `if` statement too long to omit braces.
if (condition1 &amp;&amp;
condition2)
DoSomething();
</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
non-trivial fall-through between cases.
Braces are optional for single-statement loops.
Empty loop bodies should use either empty braces or <code>continue</code>.</p>
<pre class="neutralcode">// OK - fits on one line.
if (x == kFoo) { return new Foo(); }
<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>
// OK - braces are optional in this case.
if (x == kFoo) return new Foo();
<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:
// OK - condition fits on one line, body fits on another.
if (x == kBar)
Bar(arg1, arg2, arg3);
</pre>
</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) {
case 0: { // 2 space indent
... // 4 space indent
break;
}
case 1: {
...
Foo(); // 4 space indent
break;
}
default: {
assert(false);
Bar();
}
}
</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
<code>continue</code> with no braces, rather than a single semicolon.</p>
<pre>while (condition) {
// Repeat test until it returns false.
<pre>while (condition) {} // Good - `{}` indicates no logic.
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 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>
<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
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
reference decorations. Such declarations are easily misread.
reference decorations. Such declarations are easily misread.</p>
<pre>// Fine if helpful for readability.
int x, y;
</pre>