diff options
author | Titus Winters <titus@google.com> | 2018-02-15 16:51:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-15 16:51:35 -0500 |
commit | a17678193a93dddfafca1931db0955a929a268a4 (patch) | |
tree | 04d7786124148012f1ce324912baef19a1e2d932 | |
parent | cfce3c3a866cfa9ec12fff08d5e575ca875f787b (diff) | |
parent | 6dfd9d9de92552b0fa4c79c05259b68a15defb8f (diff) | |
download | google-styleguide-a17678193a93dddfafca1931db0955a929a268a4.tar.gz |
Merge pull request #327 from pwnall/update_cpp
Update C++ styleguide to revision 3.277
-rw-r--r-- | cppguide.html | 1061 |
1 files changed, 655 insertions, 406 deletions
diff --git a/cppguide.html b/cppguide.html index 590cc9f..7f837ac 100644 --- a/cppguide.html +++ b/cppguide.html @@ -1,11 +1,11 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> -<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<meta charset="utf-8"> <title>Google C++ Style Guide</title> -<link rel="stylesheet" type="text/css" href="include/styleguide.css"> -<script language="javascript" src="include/styleguide.js"></script> -<link rel="shortcut icon" type="image/x-icon" href="https://www.google.com/favicon.ico" /> +<link rel="stylesheet" href="include/styleguide.css"> +<script src="include/styleguide.js"></script> +<link rel="shortcut icon" href="https://www.google.com/favicon.ico"> </head> <body onload="initStyleGuide();"> <div id="content"> @@ -427,10 +427,14 @@ as follows:</p> <ol> <li><code><var>dir2/foo2</var>.h</code>.</li> + <li>A blank line</li> + <li>C system files.</li> <li>C++ system files.</li> + <li>A blank line</li> + <li>Other libraries' <code>.h</code> files.</li> @@ -439,6 +443,8 @@ as follows:</p> files.</li> </ol> +<p>Note that any adjacent blank lines should be collapsed.</p> + <p>With the preferred ordering, if <code><var>dir2/foo2</var>.h</code> omits any necessary includes, the build of <code><var>dir/foo</var>.cc</code> @@ -455,6 +461,11 @@ directories too.</p> +<p>Note that the C compatibility headers such as <code>stddef.h</code> +are essentially interchangeable with their C++ counterparts +(<code>cstddef</code>) +Either style is acceptable, but prefer consistency with existing code.</p> + <p>Within each section the includes should be ordered alphabetically. Note that older code might not conform to this rule and should be fixed when convenient.</p> @@ -480,8 +491,6 @@ might look like this:</p> #include <sys/types.h> #include <unistd.h> - -#include <hash_map> #include <vector> #include "base/basictypes.h" @@ -545,15 +554,15 @@ can continue to refer to <code>Foo</code> without the prefix.</p> the enclosing scope. Consider the following snippet, for example:</p> -<pre>namespace X { -inline namespace Y { +<pre>namespace outer { +inline namespace inner { void foo(); -} // namespace Y -} // namespace X +} // namespace inner +} // namespace outer </pre> -<p>The expressions <code>X::Y::foo()</code> and -<code>X::foo()</code> are interchangeable. Inline +<p>The expressions <code>outer::inner::foo()</code> and +<code>outer::foo()</code> are interchangeable. Inline namespaces are primarily intended for ABI compatibility across versions.</p> </div> @@ -621,13 +630,13 @@ void MyClass::Foo() { DEFINE_FLAG(bool, someflag, false, "dummy flag"); -namespace a { +namespace mynamespace { using ::foo::bar; -...code for a... // Code goes against the left margin. +...code for mynamespace... // Code goes against the left margin. -} // namespace a +} // namespace mynamespace </pre> </li> @@ -690,11 +699,11 @@ of these constructs in <code>.h</code> files. <div class="stylebody"> <div class="definition"> -<p>All declarations can be given internal linkage by placing them in -unnamed namespaces, and functions and variables can be given internal linkage by +<p>All declarations can be given internal linkage by placing them in unnamed +namespaces. Functions and variables can also be given internal linkage by declaring them <code>static</code>. This means that anything you're declaring -can't be accessed from another file. If a different file declares something -with the same name, then the two entities are completely independent.</p> +can't be accessed from another file. If a different file declares something with +the same name, then the two entities are completely independent.</p> </div> <div class="decision"> @@ -717,10 +726,9 @@ Do not use internal linkage in <code>.h</code> files.</p> <div class="summary"> <p>Prefer placing nonmember functions in a namespace; use completely global -functions rarely. Prefer grouping functions with a namespace instead of -using a class as if it were a namespace. Static methods of a class should -generally be closely related to instances of the class or the class's static -data.</p> +functions rarely. Do not use a class simply to group static functions. Static +methods of a class should generally be closely related to instances of the +class or the class's static data.</p> </div> <div class="stylebody"> @@ -743,26 +751,9 @@ function not bound to a class instance. Such a function can be either a static member or a nonmember function. Nonmember functions should not depend on external variables, and should nearly always exist in a namespace. -Rather than creating classes only to group static member -functions which do not share static data, use -<a href="#Namespaces">namespaces</a> instead. For a header -<code>myproject/foo_bar.h</code>, for example, write</p> -<pre>namespace myproject { -namespace foo_bar { -void Function1(); -void Function2(); -} // namespace foo_bar -} // namespace myproject -</pre> -<p>instead of</p> -<pre class="badcode">namespace myproject { -class FooBar { - public: - static void Function1(); - static void Function2(); -}; -} // namespace myproject -</pre> +Do not create classes only to group static member functions; +this is no different than just giving the function names a +common prefix, and such grouping is usually unnecessary anyway.</p> <p>If you define a nonmember function and it is only needed in its <code>.cc</code> file, use @@ -838,85 +829,281 @@ for (int i = 0; i < 1000000; ++i) { <h3 id="Static_and_Global_Variables">Static and Global Variables</h3> <div class="summary"> - <p>Variables of class type with <a href="http://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration"> - static storage duration</a> are forbidden: they cause hard-to-find bugs due - to indeterminate order of construction and destruction. However, such - variables are allowed if they are <code>constexpr</code>: they have no - dynamic initialization or destruction.</p> +<p>Objects with +<a href="http://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration"> +static storage duration</a> are forbidden unless they are +<a href="http://en.cppreference.com/w/cpp/types/is_destructible">trivially +destructible</a>. Informally this means that the destructor does not do +anything, even taking member and base destructors into account. More formally it +means that the type has no user-defined or virtual destructor and that all bases +and non-static members are trivially destructible. +Static function-local variables may use dynamic initialization. +Use of dynamic initialization for static class member variables or variables at +namespace scope is discouraged, but allowed in limited circumstances; see below +for details.</p> + +<p>As a rule of thumb: a global variable satisfies these requirements if its +declaration, considered in isolation, could be <code>constexpr</code>.</p> </div> <div class="stylebody"> -<p>Objects with static storage duration, including global -variables, static variables, static class member -variables, and function static variables, must be Plain -Old Data (POD): only ints, chars, floats, or pointers, or -arrays/structs of POD.</p> - -<p>The order in which class constructors and initializers -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 non-local 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. 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> +<div class="definition"> +<p>Every object has a <dfn>storage duration</dfn>, which correlates with its +lifetime. Objects with static storage duration live from the point of their +initialization until the end of the program. Such objects appear as variables at +namespace scope ("global variables"), as static data members of classes, or as +function-local variables that are declared with the <code>static</code> +specifier. Function-local static variables are initialized when control first +passes through their declaration; all other objects with static storage duration +are initialized as part of program start-up. All objects with static storage +duration are destroyed at program exit (which happens before unjoined threads +are terminated).</p> + +<p>Initialization may be <dfn>dynamic</dfn>, which means that something +non-trivial happens during initialization. (For example, consider a constructor +that allocates memory, or a variable that is initialized with the current +process ID.) The other kind of initialization is <dfn>static</dfn> +initialization. The two aren't quite opposites, though: static +initialization <em>always</em> happens to objects with static storage duration +(initializing the object either to a given constant or to a representation +consisting of all bytes set to zero), whereas dynamic initialization happens +after that, if required.</p> +</div> -<p>Likewise, global and static variables are destroyed -when the program terminates, regardless of whether the -termination is by returning from <code>main()</code> or -by calling <code>exit()</code>. The order in which -destructors are called is defined to be the reverse of -the order in which the constructors were called. Since -constructor order is indeterminate, so is destructor -order. For example, at program-end time a static variable -might have been destroyed, but code still running -— perhaps in another thread -— tries to access it and fails. Or the -destructor for a static <code>string</code> variable -might be run prior to the destructor for another variable -that contains a reference to that string.</p> - -<p>One way to alleviate the destructor problem is to -terminate the program by calling -<code>quick_exit()</code> instead of <code>exit()</code>. -The difference is that <code>quick_exit()</code> does not -invoke destructors and does not invoke any handlers that -were registered by calling <code>atexit()</code>. If you -have a handler that needs to run when a program -terminates via <code>quick_exit()</code> (flushing logs, -for example), you can register it using -<code>at_quick_exit()</code>. (If you have a handler that -needs to run at both <code>exit()</code> and -<code>quick_exit()</code>, you need to register it in -both places.)</p> - -<p>As a result we only allow static variables to contain -POD data. This rule completely disallows -<code>std::vector</code> (use C arrays instead), or -<code>string</code> (use <code>const char []</code>).</p> - - - -<p>If you need a static or global -variable of a class type, consider initializing a pointer -(which will never be freed), from either your main() -function or from pthread_once(). Note that this must be a -raw pointer, not a "smart" pointer, since the smart -pointer's destructor will have the order-of-destructor -issue that we are trying to avoid.</p> +<div class="pros"> +<p>Global and static variables are very useful for a large number of +applications: named constants, auxiliary data structures internal to some +translation unit, command-line flags, logging, registration mechanisms, +background infrastructure, etc.</p> +</div> +<div class="cons"> +<p>Global and static variables that use dynamic initialization or have +non-trivial destructors create complexity that can easily lead to hard-to-find +bugs. Dynamic initialization is not ordered across translation units, and +neither is destruction (except that destruction +happens in reverse order of initialization). When one initialization refers to +another variable with static storage duration, it is possible that this causes +an object to be accessed before its lifetime has begun (or after its lifetime +has ended). Moreover, when a program starts threads that are not joined at exit, +those threads may attempt to access objects after their lifetime has ended if +their destructor has already run.</p> +</div> + +<div class="decision"> +<h4>Decision on destruction</h4> + +<p>When destructors are trivial, their execution is not subject to ordering at +all (they are effectively not "run"); otherwise we are exposed to the risk of +accessing objects after the end of their lifetime. Therefore, we only allow +objects with static storage duration if they are trivially destructible. +Fundamental types (like pointers and <code>int</code>) are trivially +destructible, as are arrays of trivially destructible types. Note that +variables marked with <code>constexpr</code> are trivially destructible.</p> +<pre>const int kNum = 10; // allowed + +struct X { int n; }; +const X kX[] = {{1}, {2}, {3}}; // allowed + +void foo() { + static const char* const kMessages[] = {"hello", "world"}; // allowed +} +// allowed: constexpr guarantees trivial destructor +constexpr std::array<int, 3> kArray = {{1, 2, 3}};</pre> +<pre class="badcode">// bad: non-trivial destructor +const string kFoo = "foo"; +// bad for the same reason, even though kBar is a reference (the +// rule also applies to lifetime-extended temporary objects) +const string& kBar = StrCat("a", "b", "c"); +void bar() { + // bad: non-trivial destructor + static std::map<int, int> kData = {{1, 0}, {2, 0}, {3, 0}}; +}</pre> + +<p>Note that references are not objects, and thus they are not subject to the +constraints on destructibility. The constraint on dynamic initialization still +applies, though. In particular, a function-local static reference of the form +<code>static T& t = *new T;</code> is allowed.</p> + +<h4>Decision on initialization</h4> + +<p>Initialization is a more complex topic. This is because we must not only +consider whether class constructors execute, but we must also consider the +evaluation of the initializer:</p> +<pre class="neutralcode">int n = 5; // fine +int m = f(); // ? (depends on f) +Foo x; // ? (depends on Foo::Foo) +Bar y = g(); // ? (depends on g and on Bar::Bar)</pre> + +<p>All but the first statement expose us to indeterminate initialization +ordering.</p> + +<p>The concept we are looking for is called <em>constant initialization</em> in +the formal language of the C++ standard. It means that the initializing +expression is a constant expression, and if the object is initialized by a +constructor call, then the constructor must be specified as +<code>constexpr</code>, too:</p> +<pre>struct Foo { constexpr Foo(int) {} }; + +int n = 5; // fine, 5 is a constant expression +Foo x(2); // fine, 2 is a constant expression and the chosen constructor is constexpr +Foo a[] = { Foo(1), Foo(2), Foo(3) }; // fine</pre> + +<p>Constant initialization is always allowed. Constant initialization of +static storage duration variables should be marked with <code>constexpr</code> +where possible. Any non-local static storage +duration variable that is not so marked should be presumed to have +dynamic initialization, and reviewed very carefully.</p> + +<p>By contrast, the following initializations are problematic:</p> + +<pre class="neutralcode">time_t time(time_t*); // not constexpr! +int f(); // not constexpr! +struct Bar { Bar() {} }; + +time_t m = time(nullptr); // initializing expression not a constant expression +Foo y(f()); // ditto +Bar b; // chosen constructor Bar::Bar() not constexpr</pre> + +<p>Dynamic initialization of nonlocal variables is discouraged, and in general +it is forbidden. However, we do permit it if no aspect of the program depends +on the sequencing of this initialization with respect to all other +initializations. Under those restrictions, the ordering of the initialization +does not make an observable difference. For example:</p> +<pre>int p = getpid(); // allowed, as long as no other static variable + // uses p in its own initialization</pre> + +<p>Dynamic initialization of static local variables is allowed (and common).</p> + + +</div> + +<h4>Common patterns</h4> + +<ul> + <li>Global strings: if you require a global or static string constant, + consider using a simple character array, or a char pointer to the first + element of a string literal. String literals have static storage duration + already and are usually sufficient.</li> + <li>Maps, sets, and other dynamic containers: if you require a static, fixed + collection, such as a set to search against or a lookup table, you cannot + use the dynamic containers from the standard library as a static variable, + since they have non-trivial destructors. Instead, consider a simple array of + trivial types, e.g. an array of arrays of ints (for a "map from int to + int"), or an array of pairs (e.g. pairs of <code>int</code> and <code>const + char*</code>). For small collections, linear search is entirely sufficient + (and efficient, due to memory locality). If necessary, keep the collection in + sorted order and use a binary search algorithm. 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 + 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 + dynamically allocated object and never delete it (see last item).</li> + <li>Static variables of custom types: if you require static, constant data of + a type that you need to define yourself, give the type a trivial destructor + and a <code>constexpr</code> constructor.</li> + <li>If all else fails, you can create an object dynamically and never delete + it by binding the pointer to a function-local static pointer variable: + <code>static const auto* const impl = new T(args...);</code> (If the + initialization is more complex, it can be moved into a function or lambda + expression.)</li> +</ul> </div> +<h3 id="thread_local">thread_local Variables</h3> + +<div class="summary"> +<p><code>thread_local</code> variables that aren't declared inside a function +must be initialized with a true compile-time constant. Prefer +<code>thread_local</code> over other ways of defining thread-local data.</p> +</div> + +<div class="stylebody"> + +<div class="definition"> +<p>Starting with C++11, variables can be declared with the +<code>thread_local</code> specifier:</p> +<pre>thread_local Foo foo = ...; +</pre> +<p>Such a variable is actually a collection of objects, so that when different +threads access it, they are actually accessing different objects. +<code>thread_local</code> variables are much like +<a href="#Static_and_Global_Variables">static storage duration variables</a> +in many respects. For instance, they can be declared at namespace scope, +inside functions, or as static class members, but not as ordinary class +members.</p> + +<p><code>thread_local</code> variable instances are initialized much like +static variables, except that they must be initialized separately for each +thread, rather than once at program startup. This means that +<code>thread_local</code> variables declared within a function are safe, but +other <code>thread_local</code> variables are subject to the same +initialization-order issues as static variables (and more besides).</p> + +<p><code>thread_local</code> variable instances are destroyed when their thread +terminates, so they do not have the destruction-order issues of static +variables.</p> +</div> + +<div class="pros"> +<ul> + <li>Thread-local data is inherently safe from races (because only one thread + can ordinarily access it), which makes <code>thread_local</code> useful for + concurrent programming.</li> + <li><code>thread_local</code> is the only standard-supported way of creating + thread-local data.</li> +</ul> +</div> + +<div class="cons"> +<ul> + <li>Accessing a <code>thread_local</code> variable may trigger execution of + an unpredictable and uncontrollable amount of other code.</li> + <li><code>thread_local</code> variables are effectively global variables, + and have all the drawbacks of global variables other than lack of + thread-safety.</li> + <li>The memory consumed by a <code>thread_local</code> variable scales with + the number of running threads (in the worst case), which can be quite large + in a program.</li> + <li>An ordinary class member cannot be <code>thread_local</code>.</li> + <li><code>thread_local</code> may not be as efficient as certain compiler + intrinsics.</li> +</ul> +</div> + +<div class="decision"> + <p><code>thread_local</code> variables inside a function have no safety + concerns, so they can be used without restriction. Note that you can use + a function-scope <code>thread_local</code> to simulate a class- or + namespace-scope <code>thread_local</code> by defining a function or + static method that exposes it:</p> + +<pre>Foo& MyThreadLocalFoo() { + thread_local Foo result = ComplicatedInitialization(); + return result; +} +</pre> + + <p><code>thread_local</code> variables at class or namespace scope must be + initialized with a true compile-time constant (i.e. they must have no + dynamic initialization). </p> + + + + <p><code>thread_local</code> should be preferred over other mechanisms for + defining thread-local data.</p> +</div> + +</div> + + <h2 id="Classes">Classes</h2> <p>Classes are the fundamental unit of code in C++. Naturally, @@ -1086,7 +1273,7 @@ your project leads to request a waiver of this rule.</p> <p>Constructors that cannot be called with a single argument -should usually omit <code>explicit</code>. Constructors that +may omit <code>explicit</code>. Constructors that take a single <code>std::initializer_list</code> parameter should also omit <code>explicit</code>, in order to support copy-initialization (e.g. <code>MyType m = {1, 2};</code>).</p> @@ -1097,25 +1284,32 @@ also omit <code>explicit</code>, in order to support copy-initialization <h3 id="Copyable_Movable_Types">Copyable and Movable Types</h3> <a id="Copy_Constructors"></a> <div class="summary"> -<p>Support copying and/or moving if these operations are clear and meaningful -for your type. Otherwise, disable the implicitly generated special functions -that perform copies and moves. -</p></div> +<p>A class's public API should make explicit whether the class is copyable, +move-only, or neither copyable nor movable. Support copying and/or +moving if these operations are clear and meaningful for your type.</p> +</div> <div class="stylebody"> <div class="definition"> -<p>A copyable type allows its objects to be initialized or assigned -from any other object of the same type, without changing the value of the source. -For user-defined types, the copy behavior is defined by the copy -constructor and the copy-assignment operator. -<code>string</code> is an example of a copyable type.</p> - <p>A movable type is one that can be initialized and assigned -from temporaries (all copyable types are therefore movable). +from temporaries.</p> + +<p>A copyable type is one that can be initialized or assigned from +any other object of the same type (so is also movable by definition), with the +stipulation that the value of the source does not change. <code>std::unique_ptr<int></code> is an example of a movable but not -copyable type. For user-defined types, the move behavior is defined by the move -constructor and the move-assignment operator.</p> +copyable type (since the value of the source +<code>std::unique_ptr<int></code> must be modified during assignment to +the destination). <code>int</code> and <code>string</code> are examples of +movable types that are also copyable. (For <code>int</code>, the move and copy +operations are the same; for <code>string</code>, there exists a move operation +that is less expensive than a copy.)</p> + +<p>For user-defined types, the copy behavior is defined by the copy +constructor and the copy-assignment operator. Move behavior is defined by the +move constructor and the move-assignment operator, if they exist, or by the +copy constructor and the copy-assignment operator otherwise.</p> <p>The copy/move constructors can be implicitly invoked by the compiler in some situations, e.g. when passing objects by value.</p> @@ -1170,49 +1364,82 @@ encourage excessive copying, which can cause performance problems.</p> <div class="decision"> -<p>Provide the copy and move operations if their meaning is clear to a casual -user and the copying/moving does not incur unexpected costs. If you define a -copy or move constructor, define the corresponding assignment operator, and -vice-versa. If your type is copyable, do not define move operations unless they -are significantly more efficient than the corresponding copy operations. If your -type is not copyable, but the correctness of a move is obvious to users of the -type, you may make the type move-only by defining both of the move operations. -</p> +<p>Every class's public interface should make explicit which copy and move +operations the class supports. This should usually take the form of explicitly +declaring and/or deleting the appropriate operations in the <code>public</code> +section of the declaration.</p> -<p>If your type provides copy operations, it is recommended that you design -your class so that the default implementation of those operations is correct. -Remember to review the correctness of any defaulted operations as you would any -other code, and to document that your class is copyable and/or cheaply movable -if that's an API guarantee.</p> +<p>Specifically, a copyable class should explicitly declare the copy +operations, a move-only class should explicitly declare the move operations, +and a non-copyable/movable class should explicitly delete the copy operations. +Explicitly declaring or deleting all four copy/move operations is permitted, +but not required. If you provide a copy or move assignment operator, you +must also provide the corresponding constructor.</p> -<pre class="badcode">class Foo { +<pre>class Copyable { public: - Foo(Foo&& other) : field_(other.field) {} - // Bad, defines only move constructor, but not operator=. + Copyable(const Copyable& rhs) = default; + Copyable& operator=(const Copyable& rhs) = default; - private: - Field field_; + // The implicit move operations are suppressed by the declarations above. +}; + +class MoveOnly { + public: + MoveOnly(MoveOnly&& rhs); + MoveOnly& operator=(MoveOnly&& rhs); + + // The copy operations are implicitly deleted, but you can + // spell that out explicitly if you want: + MoveOnly(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = delete; +}; + +class NotCopyableOrMovable { + public: + // Not copyable or movable + NotCopyableOrMovable(const NotCopyableOrMovable&) = delete; + NotCopyableOrMovable& operator=(const NotCopyableOrMovable&) + = delete; + + // The move operations are implicitly disabled, but you can + // spell that out explicitly if you want: + NotCopyableOrMovable(NotCopyableOrMovable&&) = delete; + NotCopyableOrMovable& operator=(NotCopyableOrMovable&&) + = delete; }; </pre> -<p>Due to the risk of slicing, avoid providing an assignment -operator or public copy/move constructor for a class that's -intended to be derived from (and avoid deriving from a class +<p>These declarations/deletions can be omitted only if they are obvious: for +example, if a base class isn't copyable or movable, derived classes naturally +won't be either. Similarly, a <a href="#Structs_vs._Classes">struct</a>'s +copyability/movability is normally determined by the copyability/movability +of its data members (this does not apply to classes because in Google code +their data members are not public). Note that if you explicitly declare or +delete any of the copy/move operations, the others are not obvious, and so +this paragraph does not apply (in particular, the rules in this section +that apply to "classes" also apply to structs that declare or delete any +copy/move operations).</p> + +<p>A type should not be copyable/movable if the meaning of +copying/moving is unclear to a casual user, or if it incurs unexpected +costs. Move operations for copyable types are strictly a performance +optimization and are a potential source of bugs and complexity, so +avoid defining them unless they are significantly more efficient than +the corresponding copy operations. If your type provides copy operations, it is +recommended that you design your class so that the default implementation of +those operations is correct. Remember to review the correctness of any +defaulted operations as you would any other code.</p> + +<p>Due to the risk of slicing, prefer to avoid providing a public assignment +operator or copy/move constructor for a class that's +intended to be derived from (and prefer to avoid deriving from a class with such members). If your base class needs to be copyable, provide a public virtual <code>Clone()</code> method, and a protected copy constructor that derived classes can use to implement it.</p> -<p>If you do not want to support copy/move operations on your type, -explicitly disable them using <code>= delete</code> in -the <code>public:</code> section:</p> -<pre class="code">// MyClass is neither copyable nor movable. -MyClass(const MyClass&) = delete; -MyClass& operator=(const MyClass&) = delete; -</pre> - -<p></p> </div> </div> @@ -1294,9 +1521,7 @@ implementing a sub-class is spread between the base and the sub-class, it can be more difficult to understand an implementation. The sub-class cannot override functions that are not virtual, so the sub-class cannot change -implementation. The base class may also define some data -members, so that specifies physical layout of the base -class.</p> +implementation.</p> </div> <div class="decision"> @@ -1312,23 +1537,15 @@ subclasses <code>Foo</code> if it can reasonably be said that <code>Bar</code> "is a kind of" <code>Foo</code>.</p> -<p>Make your destructor <code>virtual</code> if -necessary. If your class has virtual methods, its -destructor should be virtual.</p> - <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> -<p>Explicitly annotate overrides of virtual functions -or virtual destructors with an <code>override</code> -or (less frequently) <code>final</code> specifier. -Older (pre-C++11) code will use the -<code>virtual</code> keyword as an inferior -alternative annotation. For clarity, use exactly one of -<code>override</code>, <code>final</code>, or -<code>virtual</code> when declaring an override. +<p>Explicitly annotate overrides of virtual functions or virtual +destructors with exactly one of an <code>override</code> or (less +frequently) <code>final</code> specifier. Do not +use <code>virtual</code> when declaring an override. Rationale: A function or destructor marked <code>override</code> or <code>final</code> that is not an override of a base class virtual function will @@ -1594,14 +1811,20 @@ apply to operator overloading as well.</p> <div class="summary"> <p> Make data members <code>private</code>, unless they are <code>static const</code> (and follow the <a href="#Constant_Names"> -naming convention for constants</a>). For technical +naming convention for constants</a>).</p> +</div> + +<div class="stylebody"> + +<p>For technical reasons, we allow data members of a test fixture class to be <code>protected</code> when using <a href="https://github.com/google/googletest">Google Test</a>).</p> -</div> + +</div> <h3 id="Declaration_Order">Declaration Order</h3> @@ -1634,24 +1857,33 @@ Functions</a> for more details.</p> <h2 id="Functions">Functions</h2> -<h3 id="Function_Parameter_Ordering">Parameter Ordering</h3> +<a id="Function_Parameter_Ordering"></a> +<h3 id="Output_Parameters">Output Parameters</h3> <div class="summary"> -<p>When defining a function, parameter order is: inputs, then -outputs.</p> +<p>Prefer using return values rather than output parameters. +If output-only parameters are used they should appear after +input parameters.</p> </div> <div class="stylebody"> -<p>Parameters to C/C++ functions are either input to the -function, output from the function, or both. Input -parameters are usually values or <code>const</code> -references, while output and input/output parameters will -be pointers to non-<code>const</code>. When ordering -function parameters, put all input-only parameters before -any output parameters. In particular, do not add new -parameters to the end of the function just because they -are new; place new input-only parameters before the -output parameters.</p> +<p>The output of a C++ function is naturally provided via +a return value and sometimes via output parameters.</p> + +<p>Prefer using return values instead of output parameters +since they improve readability and oftentimes provide the same +or better performance.</p> + +<p>Parameters are either input to the function, output from the +function, or both. Input parameters are usually values or +<code>const</code> references, while output and input/output +parameters will be pointers to non-<code>const</code>.</p> + +<p>When ordering function parameters, put all input-only +parameters before any output parameters. In particular, +do not add new parameters to the end of the function just +because they are new; place new input-only parameters before +the output parameters.</p> <p>This is not a hard-and-fast rule. Parameters that are both input and output (often classes/structs) muddy the @@ -1773,7 +2005,9 @@ which overload is being called.</p> <div class="definition"> <p>You may write a function that takes a <code>const string&</code> and overload it with another that -takes <code>const char*</code>.</p> +takes <code>const char*</code>. However, in this case consider +std::string_view + instead.</p> <pre>class MyClass { public: @@ -1800,13 +2034,13 @@ function.</p> </div> <div class="decision"> -<p>If you want to overload a function, consider qualifying -the name with some information about the arguments, e.g., -<code>AppendString()</code>, <code>AppendInt()</code> -rather than just <code>Append()</code>. If you are -overloading a function to support variable number of -arguments of the same type, consider making it take a -<code>std::vector</code> so that the user can use an +<p>You may overload a function when there are no semantic +differences between variants, or when the differences are +clear at the callsite.</p> + +<p>If you are overloading a function to support variable +number of arguments of the same type, consider making it +take a <code>std::vector</code> so that the user can use an <a href="#Braced_Initializer_List">initializer list </a> to specify the arguments.</p> </div> @@ -1907,9 +2141,13 @@ doubt, use overloads.</p> after the function's parameter list has already appeared. This is particularly true when the return type depends on template parameters. For example:</p> - <pre>template <class T, class U> auto add(T t, U u) -> decltype(t + u);</pre> + <pre> template <typename T, typename U> + auto add(T t, U u) -> decltype(t + u); + </pre> versus - <pre>template <class T, class U> decltype(declval<T&>() + declval<U&>()) add(T t, U u);</pre> + <pre> template <typename T, typename U> + decltype(declval<T&>() + declval<U&>()) add(T t, U u); + </pre> </div> <div class="cons"> @@ -2085,8 +2323,7 @@ do use shared ownership, prefer to use <h3 id="cpplint">cpplint</h3> <div class="summary"> -<p>Use <code>cpplint.py</code> -to detect style errors.</p> +<p>Use <code>cpplint.py</code> to detect style errors.</p> </div> <div class="stylebody"> @@ -2322,13 +2559,107 @@ exceptions in Google open-source projects as well. Things would probably be different if we had to do it all over again from scratch.</p> -<p>This prohibition also applies to the exception-related -features added in C++11, such as <code>noexcept</code>, -<code>std::exception_ptr</code>, and +<p>This prohibition also applies to the exception handling related +features added in C++11, such as +<code>std::exception_ptr</code> and <code>std::nested_exception</code>.</p> <p>There is an <a href="#Windows_Code">exception</a> to this rule (no pun intended) for Windows code.</p> + +</div> + +</div> + +<h3 id="noexcept"><code>noexcept</code></h3> + +<div class="summary"> +<p>Specify <code>noexcept</code> when it is useful and correct.</p> +</div> + +<div class="stylebody"> +<div class="definition"> +<p>The <code>noexcept</code> specifier is used to specify whether +a function will throw exceptions or not. If an exception +escapes from a function marked <code>noexcept</code>, the program +crashes via <code>std::terminate</code>.</p> + +<p>The <code>noexcept</code> operator performs a compile-time +check that returns true if an expression is declared to not +throw any exceptions.</p> + +</div> + +<div class="pros"> +<ul> + <li>Specifying move constructors as <code>noexcept</code> + improves performance in some cases, e.g. + <code>std::vector<T>::resize()</code> moves rather than + copies the objects if T's move constructor is + <code>noexcept</code>.</li> + + <li>Specifying <code>noexcept</code> on a function can + trigger compiler optimizations in environments where + exceptions are enabled, e.g. compiler does not have to + generate extra code for stack-unwinding, if it knows + that no exceptions can be thrown due to a + <code>noexcept</code> specifier.</li> +</ul> +</div> + +<div class="cons"> +<ul> + <li> + + In projects following this guide + that have exceptions disabled it is hard + to ensure that <code>noexcept</code> + specifiers are correct, and hard to define what + correctness even means.</li> + + <li>It's hard, if not impossible, to undo <code>noexcept</code> + because it eliminates a guarantee that callers may be relying + on, in ways that are hard to detect.</li> +</ul> +</div> + +<div class="decision"> +<p>You may use <code>noexcept</code> when it is useful for +performance if it accurately reflects the intended semantics +of your function, i.e. that if an exception is somehow thrown +from within the function body then it represents a fatal error. +You can assume that <code>noexcept</code> on move constructors +has a meaningful performance benefit. If you think +there is significant performance benefit from specifying +<code>noexcept</code> on some other function, please discuss it +with +your project leads.</p> + +<p>Prefer unconditional <code>noexcept</code> if exceptions are +completely disabled (i.e. most Google C++ environments). +Otherwise, use conditional <code>noexcept</code> specifiers +with simple conditions, in ways that evaluate false only in +the few cases where the function could potentially throw. +The tests might include type traits check on whether the +involved operation might throw (e.g. +<code>std::is_nothrow_move_constructible</code> for +move-constructing objects), or on whether allocation can throw +(e.g. <code>absl::default_allocator_is_nothrow</code> for +standard default allocation). Note in many cases the only +possible cause for an exception is allocation failure (we +believe move constructors should not throw except due to +allocation failure), and there are many applications where it’s +appropriate to treat memory exhaustion as a fatal error rather +than an exceptional condition that your program should attempt +to recover from. Even for other +potential failures you should prioritize interface simplicity +over supporting all possible exception throwing scenarios: +instead of writing a complicated <code>noexcept</code> clause +that depends on whether a hash function can throw, for example, +simply document that your component doesn’t support hash +functions throwing and make it unconditionally +<code>noexcept</code>.</p> + </div> </div> @@ -2380,7 +2711,7 @@ objects. Consider</p> <pre>bool Base::Equal(Base* other) = 0; bool Derived::Equal(Base* other) { Derived* that = dynamic_cast<Derived*>(other); - if (that == NULL) + if (that == nullptr) return false; ... } @@ -2519,7 +2850,9 @@ RTTI section</a> for guidance on the use of <div class="summary"> <p>Use streams where appropriate, and stick to "simple" -usages.</p> +usages. Overload <code><<</code> for streaming only for types +representing values, and write only the user-visible value, not any +implementation details.</p> </div> <div class="stylebody"> @@ -2576,12 +2909,7 @@ flawed</a>.</li> <li>The streams API is subtle and complex, so programmers must -develop experience with it in order to use it effectively. -However, streams were historically banned in Google code (except -for logging and diagnostics), so Google engineers tend not to -have that experience. Consequently, streams-based code is likely -to be less readable and maintainable by Googlers than code based -on more familiar abstractions.</li> +develop experience with it in order to use it effectively.</li> <li>Resolving the many overloads of <code><<</code> is extremely costly for the compiler. When used pervasively in a @@ -2834,8 +3162,9 @@ choose a larger type.</p> <div class="stylebody"> <div class="definition"> -<p> C++ does not specify the sizes of its integer types. -Typically people assume that <code>short</code> is 16 bits, +<p> C++ does not 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> </div> @@ -2894,35 +3223,32 @@ sure to use a type that will accommodate any possible usage of your container. When in doubt, use a larger type rather than a smaller type.</p> -<p>Use care when converting integer types. Integer -conversions and promotions can cause non-intuitive -behavior. </p> +<p>Use care when converting integer types. Integer conversions and +promotions can cause undefined behavior, leading to security bugs and +other problems.</p> </div> <div class="stylepoint_subsection"> <h4>On Unsigned Integers</h4> -<p>Some people, including some textbook authors, -recommend using unsigned types to represent numbers that -are never negative. This is intended as a form of -self-documentation. However, in C, the advantages of such -documentation are outweighed by the real bugs it can -introduce. Consider:</p> - -<pre>for (unsigned int i = foo.Length()-1; i >= 0; --i) ... -</pre> - -<p>This code will never terminate! Sometimes gcc will -notice this bug and warn you, but often it will not. -Equally bad bugs can occur when comparing signed and -unsigned variables. Basically, C's type-promotion scheme -causes unsigned types to behave differently than one -might expect.</p> - -<p>So, document that a variable is non-negative using -assertions. Don't use an unsigned -type.</p> +<p>Unsigned integers are good for representing bitfields and modular +arithmetic. Because of historical accident, the C++ standard also uses +unsigned integers to represent the size of containers - many members +of the standards body believe this to be a mistake, but it is +effectively impossible to fix at this point. The fact that unsigned +arithmetic doesn't model the behavior of a simple integer, but is +instead defined by the standard to model modular arithmetic (wrapping +around on overflow/underflow), means that a significant class of bugs +cannot be diagnosed by the compiler. In other cases, the defined +behavior impedes optimization.</p> + +<p>That said, mixing signedness of integer types is responsible for an +equally large class of problems. The best advice we can provide: try +to use iterators and containers rather than pointers and sizes, try +not to mix signedness, and try to avoid unsigned types (except for +representing bitfields or modular arithmetic). Do not use an unsigned +type merely to assert that a variable is non-negative.</p> </div> </div> @@ -2938,109 +3264,27 @@ problems of printing, comparisons, and structure alignment.</p> <ul> <li> - <p><code>printf()</code> specifiers for some types - are not cleanly portable between 32-bit and 64-bit - systems. C99 defines some portable format specifiers. - Unfortunately, MSVC 7.1 does not understand some of - these specifiers and the standard is missing a few, - so we - have to define our own ugly versions in some cases - (in the style of the standard include file - <code>inttypes.h</code>):</p> - - <div> - <pre>// printf macros for size_t, in the style of inttypes.h -#ifdef _LP64 -#define __PRIS_PREFIX "z" -#else -#define __PRIS_PREFIX -#endif - -// Use these macros after a % in a printf format string -// to get correct 32/64 bit behavior, like this: -// size_t size = records.size(); -// printf("%" PRIuS "\n", size); - -#define PRIdS __PRIS_PREFIX "d" -#define PRIxS __PRIS_PREFIX "x" -#define PRIuS __PRIS_PREFIX "u" -#define PRIXS __PRIS_PREFIX "X" -#define PRIoS __PRIS_PREFIX "o" - </pre> - </div> - - <table border="1" summary="portable printf specifiers"> - <tbody><tr align="center"> - <th>Type</th> - <th>DO NOT use</th> - <th>DO use</th> - <th>Notes</th> - </tr> - - <tr align="center"> - <td><code>void *</code> (or any pointer)</td> - <td><code>%lx</code></td> - <td><code>%p</code></td> - <td></td> - </tr> - - - - <tr align="center"> - <td><code>int64_t</code></td> - <td><code>%qd</code>, <code>%lld</code></td> - <td><code>%" PRId64 "</code></td> - <td></td> - </tr> - - - - <tr align="center"> - <td><code>uint64_t</code></td> - <td><code>%qu</code>, <code>%llu</code>, - <code>%llx</code></td> - <td><code>%" PRIu64 "</code>, - <code>%" PRIx64 "</code></td> - <td></td> - </tr> - + <p>Correct portable <code>printf()</code> conversion specifiers for + some integral typedefs rely on macro expansions that we find unpleasant to + use and impractical to require (the <code>PRI</code> macros from + <code><cinttypes></code>). Unless there is no reasonable alternative + for your particular case, try to avoid or even upgrade APIs that rely on the + <code>printf</code> family. Instead use a library supporting typesafe numeric + formatting, such as + <a href="#Streams"><code>std::ostream</code></a>.</p> - <tr align="center"> - <td><code>size_t</code></td> - <td><code>%u</code></td> - <td><code>%" PRIuS "</code>, <code>%" PRIxS "</code></td> - <td> - C99 specifies <code>%zu</code></td> - </tr> - - <tr align="center"> - <td><code>ptrdiff_t</code></td> - <td><code>%d</code></td> - <td><code>%" PRIdS "</code></td> - <td> - C99 specifies <code>%td</code></td> - </tr> - - - </tbody></table> - - <p>Note that the <code>PRI*</code> macros expand to - independent strings which are concatenated by the - compiler. Hence if you are using a non-constant - format string, you need to insert the value of the - macro into the format, rather than the name. Note also - that spaces are required around the macro identifier to - separate it from the string literal. It is - still possible, as usual, to include length - specifiers, etc., after the <code>%</code> when using - the <code>PRI*</code> macros. So, e.g. - <code>printf("x = %30" PRIuS "\n", x)</code> would - expand on 32-bit Linux to <code>printf("x = %30" "u" - "\n", x)</code>, which the compiler will treat as - <code>printf("x = %30u\n", x)</code>.</p> - + <p>Unfortunately, the <code>PRI</code> macros are the only portable way to + specify a conversion for the standard bitwidth typedefs (e.g. + <code>int64_t</code>, <code>uint64_t</code>, <code>int32_t</code>, + <code>uint32_t</code>, etc). + Where possible, avoid passing arguments of types specified by bitwidth + typedefs to <code>printf</code>-based APIs. Note that it is acceptable + to use typedefs for which printf has dedicated length modifiers, such as + <code>size_t</code> (<code>z</code>), + <code>ptrdiff_t</code> (<code>t</code>), and + <code>maxint_t</code> (<code>j</code>).</p> </li> <li>Remember that <code>sizeof(void *)</code> != @@ -3063,13 +3307,12 @@ problems of printing, comparisons, and structure alignment.</p> <code>__declspec(align())</code>.</li> <li> - <p>Use the <code>LL</code> or <code>ULL</code> - suffixes as needed to create 64-bit constants. For - example:</p> + <p>Use <a href="#Casting">braced-initialization</a> as needed to create + 64-bit constants. For example:</p> -<pre>int64_t my_value = 0x123456789LL; -uint64_t my_mask = 3ULL << 48; +<pre>int64_t my_value{0x123456789}; +uint64_t my_mask{3ULL << 48}; </pre> </li> </ul> @@ -3168,30 +3411,25 @@ name (but upper case). </p> <h3 id="0_and_nullptr/NULL">0 and nullptr/NULL</h3> <div class="summary"> -<p>Use <code>0</code> for integers, <code>0.0</code> for -reals, <code>nullptr</code> (or <code>NULL</code>) for -pointers, and <code>'\0'</code> for chars.</p> +<p>Use <code>0</code> for integers, <code>0.0</code> for reals, +<code>nullptr</code> for pointers, and <code>'\0'</code> for chars.</p> </div> <div class="stylebody"> -<p>Use <code>0</code> for integers and <code>0.0</code> -for reals. This is not controversial.</p> +<p>Use <code>0</code> for integers and <code>0.0</code> for reals.</p> + +<p>For pointers (address values), there is a choice between <code>0</code>, +<code>NULL</code>, and <code>nullptr</code>. For projects that allow C++11 +features, use <code>nullptr</code>, as this provides type-safety.</p> -<p> For -pointers (address values), there is a choice between -<code>0</code>, <code>NULL</code>, and -<code>nullptr</code>. For projects that allow C++11 -features, use <code>nullptr</code>. For C++03 projects, -we prefer <code>NULL</code> because it looks like a -pointer. In fact, some C++ compilers provide special -definitions of <code>NULL</code> which enable them to -give useful warnings, particularly in situations where -<code>sizeof(NULL)</code> is not equal to -<code>sizeof(0)</code>.</p> +<p>For C++03 projects, prefer <code>NULL</code> to <code>0</code>. While the +values are equivalent, <code>NULL</code> looks more like a pointer to the +reader, and some C++ compilers provide special definitions of <code>NULL</code> +which enable them to give useful warnings.</p> -<p>Use <code>'\0'</code> for chars. This is the correct -type and also makes code more readable.</p> +<p>Use <code>'\0'</code> for the null character. Using the correct type makes +the code more readable.</p> </div> @@ -3241,8 +3479,8 @@ readability.</p> <div class="stylebody"> <div class="pros"> -<p> -</p><ul> + +<ul> <li>C++ type names can be long and cumbersome, especially when they involve templates or namespaces.</li> <li>When a C++ type name is repeated within a single declaration or a @@ -3349,7 +3587,7 @@ std::vector<string> v{"foo", "bar"}; std::vector<string> v = {"foo", "bar"}; // Usable with 'new' expressions. -auto p = new vector<string>{"foo", "bar"}; +auto p = new std::vector<string>{"foo", "bar"}; // A map can take a list of pairs. Nested braced-init-lists work. std::map<int, string> m = {{1, "one"}, {2, "2"}}; @@ -3938,7 +4176,8 @@ guide, the following C++11 features may not be used:</p> <code>Foo f = {.field = 3}</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 <code>a?:b</code> syntax.</p> + <code>alloca()</code>, and the "<a href="https://en.wikipedia.org/wiki/Elvis_operator">Elvis Operator</a>" + <code>a?:b</code>.</p> </div> <div class="pros"> @@ -3986,6 +4225,10 @@ using Bar = Foo; using other_namespace::Foo; </pre> + <p>In new code, <code>using</code> is preferable to <code>typedef</code>, + because it provides a more consistent syntax with the rest of C++ and works + with templates.</p> + <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 @@ -4031,32 +4274,32 @@ implementation retain some degree of freedom to change the alias.</p> </p> <p>For example, these aliases document how they are intended to be used in client code:</p> -<pre>namespace a { +<pre>namespace mynamespace { // 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*; +using DataPoint = foo::Bar*; // A set of measurements. Just an alias for user convenience. using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>; -} // namespace a +} // namespace mynamespace </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 { +<pre class="badcode">namespace mynamespace { // Bad: none of these say how they should be used. -using DataPoint = foo::bar::Bar*; +using DataPoint = foo::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 +} // 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> <pre>// In a .cc file -using std::unordered_set; +using foo::Bar; </pre> </div> @@ -4091,11 +4334,17 @@ more important to make your code immediately understandable by a new reader. Do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within -a word.</p> +a word. Abbreviations that would be familiar to someone +outside your project with relevant domain knowledge are OK. +As a rule of thumb, an abbreviation is probably OK if it's listed +in + +Wikipedia.</p> <pre>int price_count_reader; // No abbreviation. int num_errors; // "num" is a widespread convention. int num_dns_connections; // Most people know what "DNS" stands for. +int lstm_size; // "LSTM" is a common machine learning abbreviation. </pre> <pre class="badcode">int n; // Meaningless. @@ -4104,12 +4353,20 @@ int n_comp_conns; // Ambiguous abbreviation. int wgc_connections; // Only your group knows what this stands for. int pc_reader; // Lots of things can be abbreviated "pc". int cstmr_id; // Deletes internal letters. +FooBarRequestInfo fbri; // Not even a word. </pre> <p>Note that certain universally-known abbreviations are OK, such as <code>i</code> for an iteration variable and <code>T</code> for a template parameter.</p> +<p>For some symbols, this style guide recommends names to start with a capital +letter and to have a capital letter for each new word (a.k.a. +"<a href="https://en.wikipedia.org/wiki/Camel_case">Camel Case</a>" +or "Pascal case"). When abbreviations appear in such names, prefer to +capitalize the abbreviations as single words (i.e. <code>StartRpc()</code>, +not <code>StartRPC()</code>).</p> + <p>Template parameters should follow the naming style for their category: type template parameters should follow the rules for <a href="#Type_Names">type names</a>, and non-type template @@ -4268,9 +4525,9 @@ versus a class.</p> see <a href="http://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration"> Storage Duration</a> for details) should be named this way. This convention is optional for variables of other storage classes, e.g. automatic - variables, otherwise the usual variable naming rules apply.</p><p> + variables, otherwise the usual variable naming rules apply.</p> -</p></div> +</div> <h3 id="Function_Names">Function Names</h3> @@ -4282,11 +4539,7 @@ like variables.</p> <div class="stylebody"> <p>Ordinarily, functions should start with a capital letter and have a -capital letter for each new word -(a.k.a. "<a href="https://en.wikipedia.org/wiki/Camel_case">Camel -Case</a>" or "Pascal case"). Such names should not have -underscores. Prefer to capitalize acronyms as single words -(i.e. <code>StartRpc()</code>, not <code>StartRPC()</code>).</p> +capital letter for each new word.</p> <pre>AddTableEntry() DeleteUrl() @@ -4295,8 +4548,8 @@ OpenFileOrDie() <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> +like functions, because the fact that they're objects rather than functions +is an unimportant implementation detail.)</p> <p>Accessors and mutators (get and set functions) may be named like variables. These often correspond to actual member variables, but this is @@ -4318,7 +4571,7 @@ between nested namespaces and well-known top-level namespaces. <p>The name of a top-level namespace should usually be the name of the project or team whose code is contained in that namespace. The code in that namespace should usually be in -a directory whose basename matches the namespace name (or +a directory whose basename matches the namespace name (or in subdirectories thereof).</p> @@ -4398,7 +4651,8 @@ names are actually causing a compile-time problem.</p> <div class="summary"> <p>You're not really going to <a href="#Preprocessor_Macros"> define a macro</a>, are you? If you do, they're like this: -<code>MY_MACRO_THAT_SCARES_SMALL_CHILDREN</code>.</p> +<code>MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE</code>. +</p> </div> <div class="stylebody"> @@ -4500,7 +4754,9 @@ license used by the project (for example, Apache 2.0, BSD, LGPL, GPL).</p> <p>If you make significant changes to a file with an -author line, consider deleting the author line.</p> +author line, consider deleting the author line. +New files should usually not contain copyright notice or +author line.</p> <h4 class="stylepoint_subsection">File Contents</h4> @@ -4619,13 +4875,7 @@ Iterator* GetIterator() const; </pre> <p>However, do not be unnecessarily verbose or state the -completely obvious. Notice below that it is not necessary - to say "returns false otherwise" because this is -implied.</p> - -<pre>// Returns true if the table cannot hold any more entries. -bool IsTableFull(); -</pre> +completely obvious.</p> <p>When documenting function overrides, focus on the specifics of the override itself, rather than repeating @@ -4791,7 +5041,7 @@ one of the following remedies:</p> <li>Replace large or complex nested expressions with named variables.</li> <li>As a last resort, use comments to clarify argument meanings at the - call site.</li> + call site. </li> </ul> Consider the following example: @@ -5135,8 +5385,8 @@ not fit on a single line as you would wrap arguments in a <ul> <li>Choose good parameter names.</li> - <li>Parameter names may be omitted only if the parameter is unused and its - purpose is obvious.</li> + <li>A parameter name may be omitted only if the parameter is not used in the + function's definition.</li> <li>If you cannot fit the return type and the function name on a single line, break between them.</li> @@ -5429,7 +5679,7 @@ them; conditional or loop statements with complex conditions or statements may be more readable with curly braces. Some projects require that an -<code>if</code> must always always have an accompanying +<code>if</code> must always have an accompanying brace.</p> <pre>if (condition) @@ -5475,7 +5725,7 @@ if (condition) { <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 empty braces or <code>continue</code>.</p> +Empty loop bodies should use either empty braces or <code>continue</code>.</p> </div> <div class="stylebody"> @@ -5489,10 +5739,9 @@ should be placed as shown below.</p> 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, simply -<code>assert</code>:</p> +case should never execute, treat this as an error. For example: - +</p> <div> <pre>switch (var) { @@ -5526,8 +5775,8 @@ for (int i = 0; i < kSomeNumber; ++i) { </pre> -<p>Empty loop bodies should use an empty pair of braces or <code>continue</code>, -but not a single semicolon.</p> +<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. @@ -5582,6 +5831,11 @@ char* c; const string& str; </pre> +<p>You should do this consistently within a single +file, +so, when modifying an existing file, use the style in +that file.</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. @@ -5593,11 +5847,6 @@ char * c; // Bad - spaces on both sides of * const string & str; // Bad - spaces on both sides of & </pre> -<p>You should do this consistently within a single -file, -so, when modifying an existing file, use the style in -that file.</p> - </div> <h3 id="Boolean_Expressions">Boolean Expressions</h3> @@ -5691,8 +5940,8 @@ will call a default constructor if available. To force the non-<code>std::initializer_list</code> constructor, use parentheses instead of braces.</p> -<pre>std::vector<int> v(100, 1); // A vector of 100 1s. -std::vector<int> v{100, 1}; // A vector of 100, 1. +<pre>std::vector<int> v(100, 1); // A vector containing 100 items: All 1s. +std::vector<int> v{100, 1}; // A vector containing 2 items: 100 and 1. </pre> <p>Also, the brace form prevents narrowing of integral @@ -5867,7 +6116,7 @@ void foo() { // Correct. No extra indentation within namespace. <pre class="badcode">namespace { - // Wrong. Indented when it should not be. + // Wrong! Indented when it should not be. void foo() { ... } @@ -6138,7 +6387,7 @@ occasionally need to break on Windows:</p> </div> -<h2 class="ignoreLink">Parting Words</h2> +<h2 id="Parting_Words">Parting Words</h2> <p>Use common sense and <em>BE CONSISTENT</em>.</p> |