mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
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:
parent
e065b55718
commit
f1dbcc3382
452
cppguide.html
452
cppguide.html
|
@ -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<int> 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,8 +1834,9 @@ which overload is being called.</p>
|
|||
<p>You may write a function that takes a <code>const
|
||||
std::string&</code> and overload it with another that
|
||||
takes <code>const char*</code>. However, in this case consider
|
||||
std::string_view
|
||||
instead.</p>
|
||||
<code>std::string_view
|
||||
</code>
|
||||
instead.</p>
|
||||
|
||||
<pre>class MyClass {
|
||||
public:
|
||||
|
@ -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&&
|
||||
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 '&&' 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<float>(double_value)</code>, or brace
|
|||
initialization for conversion of arithmetic types like
|
||||
<code>int64_t y = int64_t{1} << 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><cstdint></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<WidgetWithBellsAndWhistles> widget_ptr =
|
||||
<pre class="neutralcode">std::unique_ptr<WidgetWithBellsAndWhistles> widget =
|
||||
std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
absl::flat_hash_map<std::string,
|
||||
std::unique_ptr<WidgetWithBellsAndWhistles>>::const_iterator
|
||||
it = my_map_.find(key);
|
||||
std::array<int, 6> numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||
|
||||
<pre class="goodcode">auto widget_ptr = std::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||
<pre class="goodcode">auto widget = std::make_unique<WidgetWithBellsAndWhistles>(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 & 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(&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(&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<DataPoint, hash<DataPoint>, 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) << "Invalid value in switch statement: " << 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 (&) and the variable name.</p>
|
||||
ampersand (<code>&</code>) and the variable name.</p>
|
||||
<pre>int x = 0;
|
||||
auto x_plus_n = [&x](int n) -> int { return x + n; }
|
||||
</pre>
|
||||
<p>Short lambdas may be written inline as function arguments.</p>
|
||||
<pre>std::set<int> to_remove = {7, 8, 9};
|
||||
<pre>absl::flat_hash_set<int> to_remove = {7, 8, 9};
|
||||
std::vector<int> digits = {3, 9, 1, 8, 4, 7, 1};
|
||||
digits.erase(std::remove_if(digits.begin(), digits.end(), [&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 < 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 &&
|
||||
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 < kSomeNumber; ++i)
|
||||
printf("I love you\n");
|
||||
|
||||
for (int i = 0; i < 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 < 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>
|
||||
|
|
Loading…
Reference in New Issue
Block a user