mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Update to current.
Most significant updates: * Casting (for arithmetic types, maybe use {}s) * Namespaces * Aliases
This commit is contained in:
parent
14ab228ab6
commit
0124f309e4
301
cppguide.html
301
cppguide.html
|
@ -579,6 +579,7 @@ below. Terminate namespaces with comments as shown in the
|
|||
given examples. See also the rules on
|
||||
<a href="#Namespace_Names">Namespace Names</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="stylepoint_subsection">Unnamed Namespaces</h4>
|
||||
|
||||
|
@ -679,31 +680,12 @@ using namespace foo;
|
|||
</pre>
|
||||
</li>
|
||||
|
||||
<li><p>You may use a <i>using-declaration</i>
|
||||
anywhere in a <code>.cc</code> file (including in
|
||||
the global namespace), and in functions,
|
||||
methods, classes, or within internal namespaces in
|
||||
<code>.h</code> files.</p>
|
||||
|
||||
<p>Do not use using-declarations in <code>.h</code>
|
||||
files except in explicitly marked internal-only
|
||||
namespaces, because anything imported into a namespace
|
||||
in a <code>.h</code> file becomes part of the public
|
||||
<li><p>Do not use <i>Namespace aliases</i> at namespace scope
|
||||
in header files except in explicitly marked
|
||||
internal-only namespaces, because anything imported into a namespace
|
||||
in a header file becomes part of the public
|
||||
API exported by that file.</p>
|
||||
|
||||
<pre>// OK in .cc files.
|
||||
// Must be in a function, method, internal namespace, or
|
||||
// class in .h files.
|
||||
using ::foo::bar;
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
<li><p><i>Namespace aliases</i> are allowed anywhere where
|
||||
a <i>using-declaration</i> is allowed. In particular,
|
||||
namespace aliases should not be used at namespace scope
|
||||
in <code>.h</code> files except in explicitly marked
|
||||
internal-only namespaces.</p>
|
||||
|
||||
<pre>// Shorten access to some commonly used names in .cc files.
|
||||
namespace baz = ::foo::bar::baz;
|
||||
</pre>
|
||||
|
@ -871,13 +853,14 @@ for static variables are called is only partially
|
|||
specified in C++ and can even change from build to build,
|
||||
which can cause bugs that are difficult to find.
|
||||
Therefore in addition to banning globals of class type,
|
||||
we do not allow static POD variables to be initialized
|
||||
we do not allow namespace-scope static variables to be initialized
|
||||
with the result of a function, unless that function (such
|
||||
as getenv(), or getpid()) does not itself depend on any
|
||||
other globals. (This prohibition does not apply to a static
|
||||
variable within function scope, since its initialization
|
||||
order is well-defined and does not occur until control
|
||||
passes through its declaration.)</p>
|
||||
other globals. However, a static POD variable within
|
||||
function scope may be initialized with the result of a
|
||||
function, since its initialization order is well-defined
|
||||
and does not occur until control passes through its
|
||||
declaration.</p>
|
||||
|
||||
<p>Likewise, global and static variables are destroyed
|
||||
when the program terminates, regardless of whether the
|
||||
|
@ -980,9 +963,9 @@ of the constructor.</p>
|
|||
IsValid()</code> state checking mechanism (or similar) which is easy
|
||||
to forget to call.</li>
|
||||
|
||||
<li>You cannot take address of a constructor, so whatever work is done in
|
||||
the constructor cannot easily be handed off to, for example, another
|
||||
thread.</li>
|
||||
<li>You cannot take the address of a constructor, so whatever work
|
||||
is done in the constructor cannot easily be handed off to, for
|
||||
example, another thread.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -1730,7 +1713,7 @@ are empty, omit them.</p>
|
|||
be in the following order:</p>
|
||||
|
||||
<ul>
|
||||
<li>Typedefs and Enums</li>
|
||||
<li>Using-declarations, Typedefs and Enums</li>
|
||||
|
||||
<li>Constants (<code>static const</code> data
|
||||
members)</li>
|
||||
|
@ -1943,9 +1926,11 @@ arguments of the same type, consider making it take a
|
|||
<h3 id="Default_Arguments">Default Arguments</h3>
|
||||
|
||||
<div class="summary">
|
||||
<p>We do not allow default function parameters, except in
|
||||
limited situations as explained below. Simulate them with
|
||||
function overloading instead, if appropriate.</p>
|
||||
<p>Default arguments are allowed on non-virtual functions
|
||||
when the default is guaranteed to always have the same
|
||||
value. Follow the same restrictions as for <a href="#Function_Overloading">function overloading</a>, and
|
||||
prefer overloaded functions if the readability gained with
|
||||
default arguments doesn't outweigh the downsides below.</p>
|
||||
</div>
|
||||
|
||||
<div class="stylebody">
|
||||
|
@ -1962,43 +1947,37 @@ arguments.</p>
|
|||
</div>
|
||||
|
||||
<div class="cons">
|
||||
<p>Defaulted arguments are another way to achieve the
|
||||
semantics of overloaded functions, so all the <a href="#Function_Overloading">reasons not to overload
|
||||
functions</a> apply.</p>
|
||||
|
||||
<p>The defaults for arguments in a virtual function call are
|
||||
determined by the static type of the target object, and
|
||||
there's no guarantee that all overrides of a given function
|
||||
declare the same defaults.</p>
|
||||
|
||||
<p>Default parameters are re-evaluated at each call site,
|
||||
which can bloat the generated code. Readers may also expect
|
||||
the default's value to be fixed at the declaration instead
|
||||
of varying at each call.</p>
|
||||
|
||||
<p>Function pointers are confusing in the presence of
|
||||
default arguments, since the function signature often
|
||||
doesn't match the call signature. Adding a default
|
||||
argument to an existing function changes its type, which
|
||||
can cause problems with code taking its address. Adding
|
||||
function overloads avoids these problems. In addition,
|
||||
default parameters may result in bulkier code since they
|
||||
are replicated at every call-site -- as opposed to
|
||||
overloaded functions, where "the default" appears only in
|
||||
the function definition.</p>
|
||||
doesn't match the call signature. Adding
|
||||
function overloads avoids these problems.</p>
|
||||
</div>
|
||||
|
||||
<div class="decision">
|
||||
<p>While the cons above are not that onerous, they still
|
||||
outweigh the (small) benefits of default arguments over
|
||||
function overloading. So except as described below, we
|
||||
require all arguments to be explicitly specified.</p>
|
||||
<p>Default arguments are banned on virtual functions, where
|
||||
they don't work properly, and in cases where the specified
|
||||
default might not evaluate to the same value depending on
|
||||
when it was evaluated. (For example, don't write <code>void
|
||||
f(int n = counter++);</code>.)</p>
|
||||
|
||||
<p>One specific exception is when the function is a
|
||||
static function (or in an unnamed namespace) in a .cc
|
||||
file. In this case, the cons don't apply since the
|
||||
function's use is so localized.</p>
|
||||
|
||||
<p>In addition, default function parameters are allowed in
|
||||
constructors. Most of the cons listed above don't apply to
|
||||
constructors because it's impossible to take their address.</p>
|
||||
|
||||
<p>Another specific exception is when default arguments
|
||||
are used to simulate variable-length argument lists.</p>
|
||||
|
||||
|
||||
<pre>// Support up to 4 params by using a default empty AlphaNum.
|
||||
string StrCat(const AlphaNum &a,
|
||||
const AlphaNum &b = gEmptyAlphaNum,
|
||||
const AlphaNum &c = gEmptyAlphaNum,
|
||||
const AlphaNum &d = gEmptyAlphaNum);
|
||||
</pre>
|
||||
<p>In some other cases, default arguments can improve the
|
||||
readability of their function declarations enough to
|
||||
overcome the downsides above, so they are allowed. When in
|
||||
doubt, use overloads.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -2613,9 +2592,13 @@ workarounds disguise your true intent.</p>
|
|||
<h3 id="Casting">Casting</h3>
|
||||
|
||||
<div class="summary">
|
||||
<p>Use C++ casts like <code>static_cast<>()</code>. Do
|
||||
not use other cast formats like <code>int y =
|
||||
(int)x;</code> or <code>int y = int(x);</code>.</p>
|
||||
<p>Use C++-style casts
|
||||
like <code>static_cast<float>(double_value)</code>, or brace
|
||||
initialization for conversion of arithmetic types like
|
||||
<code>int64 y = int64{1} << 42</code>. Do not use
|
||||
cast formats like
|
||||
<code>int y = (int)x</code> or <code>int y = int(x)</code> (but the latter
|
||||
is okay when invoking a constructor of a class type).</p>
|
||||
</div>
|
||||
|
||||
<div class="stylebody">
|
||||
|
@ -2627,41 +2610,49 @@ of cast operations.</p>
|
|||
</div>
|
||||
|
||||
<div class="pros">
|
||||
<p>The problem with C casts is the ambiguity of the
|
||||
operation; sometimes you are doing a <em>conversion</em>
|
||||
<p>The problem with C casts is the ambiguity of the operation;
|
||||
sometimes you are doing a <em>conversion</em>
|
||||
(e.g., <code>(int)3.5</code>) and sometimes you are doing
|
||||
a <em>cast</em> (e.g., <code>(int)"hello"</code>); C++
|
||||
casts avoid this. Additionally C++ casts are more visible
|
||||
when searching for them.</p>
|
||||
a <em>cast</em> (e.g., <code>(int)"hello"</code>). Brace
|
||||
initialization and C++ casts can often help avoid this
|
||||
ambiguity. Additionally, C++ casts are more visible when searching for
|
||||
them.</p>
|
||||
</div>
|
||||
|
||||
<div class="cons">
|
||||
<p>The syntax is nasty.</p>
|
||||
<p>The C++-style cast syntax is verbose and cumbersome.</p>
|
||||
</div>
|
||||
|
||||
<div class="decision">
|
||||
<p>Do not use C-style casts. Instead, use these C++-style
|
||||
casts. </p>
|
||||
<p>Do not use C-style casts. Instead, use these C++-style casts when
|
||||
explicit type conversion is necessary. </p>
|
||||
|
||||
<ul>
|
||||
<li>Convert arithmetic types using brace initialization. This is
|
||||
the safest approach because code will not compile if conversion can
|
||||
result in information loss. The syntax is also concise.</li>
|
||||
|
||||
|
||||
|
||||
<li>Use <code>static_cast</code> as the equivalent of a
|
||||
C-style cast that does value conversion, or when you need to explicitly up-cast a
|
||||
pointer from a class to its superclass.</li>
|
||||
<li>Use <code>static_cast</code> as the equivalent of a C-style cast
|
||||
that does value conversion, when you need to
|
||||
explicitly up-cast a pointer from a class to its superclass, or when
|
||||
you need to explicitly cast a pointer from a superclass to a
|
||||
subclass. In this last case, you must be sure your object is
|
||||
actually an instance of the subclass.</li>
|
||||
|
||||
|
||||
|
||||
<li>Use <code>const_cast</code> to remove the
|
||||
<code>const</code> qualifier (see <a href="#Use_of_const">const</a>).</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>Use <code>reinterpret_cast</code> to do unsafe
|
||||
conversions of pointer types to and from integer and
|
||||
other pointer types. Use this only if you know what you
|
||||
are doing and you understand the aliasing issues.
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
<p>See the <a href="#Run-Time_Type_Information__RTTI_">
|
||||
|
@ -2875,9 +2866,10 @@ Therefore we strongly recommend that you use
|
|||
<code>const</code> whenever it makes sense to do so:</p>
|
||||
|
||||
<ul>
|
||||
<li>If a function does not modify an argument passed by
|
||||
reference or by pointer, that argument should be
|
||||
<code>const</code>.</li>
|
||||
<li>If a function guarantees that it will not modify an argument
|
||||
passed by reference or by pointer, the corresponding function parameter
|
||||
should be a reference-to-const (<code>const T&</code>) or
|
||||
pointer-to-const (<code>const T*</code>), respectively.</li>
|
||||
|
||||
<li>Declare methods to be <code>const</code> whenever
|
||||
possible. Accessors should almost always be
|
||||
|
@ -3652,8 +3644,11 @@ current scope. For example, instead of:
|
|||
executor->Schedule([&] { Frobnicate(foo); })
|
||||
...
|
||||
}
|
||||
// BAD! `Frobnicate` may be a member function and `foo` may be destroyed
|
||||
// by the time the lambda runs.
|
||||
// BAD! The fact that the lambda makes use of a reference to `foo` and
|
||||
// possibly `this` (if `Frobnicate` is a member function) may not be
|
||||
// apparent on a cursory inspection. If the lambda is invoked after
|
||||
// the function returns, that would be bad, because both `foo`
|
||||
// and the enclosing object could have been destroyed.
|
||||
</pre>
|
||||
prefer to write:
|
||||
<pre>{
|
||||
|
@ -3662,9 +3657,9 @@ prefer to write:
|
|||
executor->Schedule([&foo] { Frobnicate(foo); })
|
||||
...
|
||||
}
|
||||
// GOOD - The lambda cannot accidentally capture `this` and
|
||||
// the explicit by-reference capture is more obvious and therefore
|
||||
// more likely to be checked for correctness.
|
||||
// BETTER - The compile will fail if `Frobnicate` is a member
|
||||
// function, and it's clearer that `foo` is dangerously captured by
|
||||
// reference.
|
||||
</pre>
|
||||
</li>
|
||||
<li>Keep unnamed lambdas short. If a lambda body is more than
|
||||
|
@ -4027,9 +4022,104 @@ guide, the following C++11 features may not be used:</p>
|
|||
<code><fenv.h></code> headers, because many
|
||||
compilers do not support those features reliably.</li>
|
||||
|
||||
<li>Ref-qualifiers on member functions, such as <code>void X::Foo()
|
||||
&</code> or <code>void X::Foo() &&</code>, because of concerns
|
||||
that they're an overly obscure feature.</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 id="Aliases">Aliases</h3>
|
||||
|
||||
<div class="summary">
|
||||
<p>Public aliases are for the benefit of an API's user, and should be clearly documented.</p>
|
||||
</div>
|
||||
<div class="stylebody">
|
||||
<div class="definition">
|
||||
<p>There are several ways to create names that are aliases of other entities:</p>
|
||||
<pre>typedef Foo Bar;
|
||||
using Bar = Foo;
|
||||
using other_namespace::Foo;
|
||||
</pre>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="pros">
|
||||
<ul>
|
||||
<li>Aliases can improve readability by simplifying a long or complicated name.</li>
|
||||
<li>Aliases can reduce duplication by naming in one place a type used repeatedly in an API,
|
||||
which <em>might</em> make it easier to change the type later.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="cons">
|
||||
<ul>
|
||||
<li>When placed in a header where client code can refer to them, aliases increase the
|
||||
number of entities in that header's API, increasing its complexity.</li>
|
||||
<li>Clients can easily rely on unintended details of public aliases, making
|
||||
changes difficult.</li>
|
||||
<li>It can be tempting to create a public alias that is only intended for use
|
||||
in the implementation, without considering its impact on the API, or on maintainability.</li>
|
||||
<li>Aliases can create risk of name collisions</li>
|
||||
<li>Aliases can reduce readability by giving a familiar construct an unfamiliar name</li>
|
||||
<li>Type aliases can create an unclear API contract:
|
||||
it is unclear whether the alias is guaranteed to be identical to the type it aliases,
|
||||
to have the same API, or only to be usable in specified narrow ways</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="decision">
|
||||
<p>Don't put an alias in your public API just to save typing in the implementation;
|
||||
do so only if you intend it to be used by your clients.</p>
|
||||
<p>When defining a public alias, document the intent of
|
||||
the new name, including whether it is guaranteed to always be the same as the type
|
||||
it's currently aliased to, or whether a more limited compatibility is
|
||||
intended. This lets the user know whether they can treat the types as
|
||||
substitutable or whether more specific rules must be followed, and can help the
|
||||
implementation retain some degree of freedom to change the alias.</p>
|
||||
<p>Don't put namespace aliases in your public API. (See also <a href="#Namespaces">Namespaces</a>).
|
||||
</p>
|
||||
|
||||
<p>For example, these aliases document how they are intended to be used in client code:</p>
|
||||
<pre>namespace a {
|
||||
// Used to store field measurements. DataPoint may change from Bar* to some internal type.
|
||||
// Client code should treat it as an opaque pointer.
|
||||
using DataPoint = foo::bar::Bar*;
|
||||
|
||||
// A set of measurements. Just an alias for user convenience.
|
||||
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
|
||||
} // namespace a
|
||||
</pre>
|
||||
|
||||
<p>These aliases don't document intended use, and half of them aren't meant for client use:</p>
|
||||
|
||||
<pre class="badcode">namespace a {
|
||||
// Bad: none of these say how they should be used.
|
||||
using DataPoint = foo::bar::Bar*;
|
||||
using std::unordered_set; // Bad: just for local convenience
|
||||
using std::hash; // Bad: just for local convenience
|
||||
typedef unordered_set<DataPoint, hash<DataPoint>, DataPointComparator> TimeSeries;
|
||||
} // namespace a
|
||||
</pre>
|
||||
|
||||
<p>However, local convenience aliases are fine in function definitions, private sections of
|
||||
classes, explicitly marked internal namespaces, and in .cc files:</p>
|
||||
|
||||
<pre>// In a .cc file
|
||||
using std::unordered_set;
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="Naming">Naming</h2>
|
||||
|
@ -4131,7 +4221,7 @@ letter for each new word, with no underscores:
|
|||
|
||||
<div class="stylebody">
|
||||
|
||||
<p>The names of all types — classes, structs, typedefs,
|
||||
<p>The names of all types — classes, structs, type aliases,
|
||||
enums, and type template parameters — have the same naming convention.
|
||||
Type names should start with a capital letter and have a capital letter
|
||||
for each new word. No underscores. For example:</p>
|
||||
|
@ -4144,6 +4234,9 @@ struct UrlTableProperties { ...
|
|||
// typedefs
|
||||
typedef hash_map<UrlTableProperties *, string> PropertiesMap;
|
||||
|
||||
// using aliases
|
||||
using PropertiesMap = hash_map<UrlTableProperties *, string>;
|
||||
|
||||
// enums
|
||||
enum UrlTableErrors { ...
|
||||
</pre>
|
||||
|
@ -4256,6 +4349,11 @@ DeleteUrl()
|
|||
OpenFileOrDie()
|
||||
</pre>
|
||||
|
||||
<p>(The same naming rule applies to class- and namespace-scope
|
||||
constants that are exposed as part of an API and that are intended to look
|
||||
like functions, because the fact that they're
|
||||
objects rather than functions is an unimportant implementation detail.)</p>
|
||||
|
||||
<p>Functions that are very cheap to call may instead follow the style
|
||||
for variable names (all lower-case, with underscores between words).
|
||||
The rule of thumb is that such a function should be so cheap that you
|
||||
|
@ -4324,7 +4422,7 @@ details from user-facing declarations, one common choice is
|
|||
<p>Preferably, the individual enumerators should be named
|
||||
like <a href="#Constant_Names">constants</a>. However, it
|
||||
is also acceptable to name them like
|
||||
<a href="Macro_Names">macros</a>. The enumeration name,
|
||||
<a href="#Macro_Names">macros</a>. The enumeration name,
|
||||
<code>UrlTableErrors</code> (and
|
||||
<code>AlternateUrlTableErrors</code>), is a type, and
|
||||
therefore mixed case.</p>
|
||||
|
@ -4837,24 +4935,23 @@ a short-term solution, or good-enough but not perfect.</p>
|
|||
<p><code>TODO</code>s should include the string
|
||||
<code>TODO</code> in all caps, followed by the
|
||||
|
||||
name, e-mail address, or other
|
||||
identifier of the person
|
||||
with the best context
|
||||
name, e-mail address, bug ID, or other
|
||||
identifier
|
||||
of the person or issue with the best context
|
||||
about the problem referenced by the <code>TODO</code>. The
|
||||
main purpose is to have a consistent <code>TODO</code> that
|
||||
can be searched to find out how to get more details upon
|
||||
request. A <code>TODO</code> is not a commitment that the
|
||||
person referenced will fix the problem. Thus when you create
|
||||
a <code>TODO</code>, it is almost always your
|
||||
|
||||
name
|
||||
that is given.</p>
|
||||
a <code>TODO</code> with a name, it is almost always your
|
||||
name that is given.</p>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<pre>// TODO(kl@gmail.com): Use a "*" here for concatenation operator.
|
||||
// TODO(Zeke) change this to use relations.
|
||||
// TODO(bug 12345): remove the "Last visitors" feature
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
@ -4974,7 +5071,7 @@ URL longer than 80 characters.</p>
|
|||
|
||||
<p class="exception">A raw-string literal may have content
|
||||
that exceeds 80 characters. Except for test code, such literals
|
||||
should appear near top of a file.</p>
|
||||
should appear near the top of a file.</p>
|
||||
|
||||
<p class="exception">An <code>#include</code> statement with a
|
||||
long path may exceed 80 columns.</p>
|
||||
|
|
Loading…
Reference in New Issue
Block a user