Google C++ Style Guide
Revision 3.180
Benjy Weinberger
Craig Silverstein
Gregory Eitzmann
Mark Mentovai
Tashana Landray
Each style point has a summary for which additional information is available
by toggling the accompanying arrow button that looks this way: ▽ . You
may toggle all summaries with the big arrow button:
▽ Toggle all summaries
Table of Contents
Important Note
Displaying Hidden Details in this Guide
This style guide contains many details that are initially hidden from view. They are marked by the triangle icon,
which you see here on your left. Click it now. You should see "Hooray" appear below.
Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of
this document.
Background
C++ is the main development language used by many of Google's open-source projects. As every C++ programmer
knows, the language has many powerful features, but this power brings with it complexity, which in turn can make
code more bug-prone and harder to read and maintain.
The goal of this guide is to manage this complexity by describing in detail the dos and don'ts of writing C++ code.
These rules exist to keep the code base manageable while still allowing coders to use C++ language features
productively.
Style, also known as readability, is what we call the conventions that govern our C++ code. The term Style is a bit of
a misnomer, since these conventions cover far more than just source file formatting.
Header
Files
The #define Guard Header File Dependencies Inline Functions The -inl.h Files
Function Parameter Ordering Names and Order of Includes
Scoping Namespaces Nested Classes Nonmember, Static Member, and Global Functions
Local Variables Static and Global Variables
Classes Doing Work in Constructors Default Constructors Explicit Constructors
Copy Constructors Structs vs. Classes Inheritance Multiple Inheritance Interfaces
Operator Overloading Access Control Declaration Order Write Short Functions
Google-
Specific
Magic
Smart Pointers cpplint
Other C++
Features
Reference Arguments Function Overloading Default Arguments
Variable-Length Arrays and alloca() Friends Exceptions
Run-Time Type Information (RTTI) Casting Streams
Preincrement and Predecrement Use of const Integer Types 64-bit Portability
Preprocessor Macros 0 and NULL sizeof Boost C++0x
Naming General Naming Rules File Names Type Names Variable Names
Constant Names Function Names Namespace Names Enumerator Names
Macro Names Exceptions to Naming Rules
Comments Comment Style File Comments Class Comments Function Comments
Variable Comments Implementation Comments Punctuation, Spelling and Grammar
TODO Comments Deprecation Comments
Formatting Line Length Non-ASCII Characters Spaces vs. Tabs
Function Declarations and Definitions Function Calls Conditionals
Loops and Switch Statements Pointer and Reference Expressions
Boolean Expressions Return Values Variable and Array Initialization
Preprocessor Directives Class Format Constructor Initializer Lists
Namespace Formatting Horizontal Whitespace Vertical Whitespace
Exceptions
to the Rules
Existing Non-conformant Code Windows Code
link ▽
One way in which we keep the code base manageable is by enforcing consistency. It is very important that any
programmer be able to look at another's code and quickly understand it. Maintaining a uniform style and following
conventions means that we can more easily use "pattern-matching" to infer what various symbols are and what
invariants are true about them. Creating common, required idioms and patterns makes code much easier to
understand. In some cases there might be good arguments for changing certain style rules, but we nonetheless keep
things as they are in order to preserve consistency.
Another issue this guide addresses is that of C++ feature bloat. C++ is a huge language with many advanced
features. In some cases we constrain, or even ban, use of certain features. We do this to keep code simple and to
avoid the various common errors and problems that these features can cause. This guide lists these features and
explains why their use is restricted.
Open-source projects developed by Google conform to the requirements in this guide.
Note that this guide is not a C++ tutorial: we assume that the reader is familiar with the language.
Header Files
In general, every .cc file should have an associated .h file. There are some common exceptions, such as unittests
and small .cc files containing just a main() function.
Correct use of header files can make a huge difference to the readability, size and performance of your code.
The following rules will guide you through the various pitfalls of using header files.
The #define Guard
All header files should have #define guards to prevent multiple inclusion. The format of the symbol name
should be
___H_.
To guarantee uniqueness, they should be based on the full path in a project's source tree. For example, the file
foo/src/bar/baz.h in project foo should have the following guard:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_
Header File Dependencies
Don't use an #include when a forward declaration would suffice.
When you include a header file you introduce a dependency that will cause your code to be recompiled whenever
the header file changes. If your header file includes other header files, any change to those files will cause any code
that includes your header to be recompiled. Therefore, we prefer to minimize includes, particularly includes of header
files in other header files.
You can significantly minimize the number of header files you need to include in your own header files by using
forward declarations. For example, if your header file uses the File class in ways that do not require access to the
declaration of the File class, your header file can just forward declare class File; instead of having to
#include "file/base/file.h".
How can we use a class Foo in a header file without access to its definition?
l We can declare data members of type Foo* or Foo&.
l We can declare (but not define) functions with arguments, and/or return values, of type Foo. (One exception
is if an argument Foo or const Foo& has a non-explicit, one-argument constructor, in which case we
need the full definition to support automatic type conversion.)
l We can declare static data members of type Foo. This is because static data members are defined outside
the class definition.
On the other hand, you must include the header file for Foo if your class subclasses Foo or has a data member of
type Foo.
Sometimes it makes sense to have pointer (or better, scoped_ptr) members instead of object members. However,
this complicates code readability and imposes a performance penalty, so avoid doing this transformation if the only
purpose is to minimize includes in header files.
Of course, .cc files typically do require the definitions of the classes they use, and usually have to include several
header files.
Note: If you use a symbol Foo in your source file, you should bring in a definition for Foo yourself, either via an
#include or via a forward declaration. Do not depend on the symbol being brought in transitively via headers not
directly included. One exception is if Foo is used in myfile.cc, it's ok to #include (or forward-declare) Foo in
myfile.h, instead of myfile.cc.
Inline Functions
link ▽
link ▽
Define functions inline only when they are small, say, 10 lines or less.
Definition:
You can declare functions in a way that allows the compiler to expand them inline rather than calling them through
the usual function call mechanism.
Pros:
Inlining a function can generate more efficient object code, as long as the inlined function is small. Feel free to inline
accessors and mutators, and other short, performance-critical functions.
Cons:
Overuse of inlining can actually make programs slower. Depending on a function's size, inlining it can cause the
code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while
inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs
faster due to better use of the instruction cache.
Decision:
A decent rule of thumb is to not inline a function if it is more than 10 lines long. Beware of destructors, which are
often longer than they appear because of implicit member- and base-destructor calls!
Another useful rule of thumb: it's typically not cost effective to inline functions with loops or switch statements
(unless, in the common case, the loop or switch statement is never executed).
It is important to know that functions are not always inlined even if they are declared as such; for example, virtual
and recursive functions are not normally inlined. Usually recursive functions should not be inline. The main reason
for making a virtual function inline is to place its definition in the class, either for convenience or to document its
behavior, e.g., for accessors and mutators.
The -inl.h Files
You may use file names with a -inl.h suffix to define complex inline functions when needed.
The definition of an inline function needs to be in a header file, so that the compiler has the definition available for
inlining at the call sites. However, implementation code properly belongs in .cc files, and we do not like to have
much actual code in .h files unless there is a readability or performance advantage.
If an inline function definition is short, with very little, if any, logic in it, you should put the code in your .h file. For
example, accessors and mutators should certainly be inside a class definition. More complex inline functions may
also be put in a .h file for the convenience of the implementer and callers, though if this makes the .h file too
unwieldy you can instead put that code in a separate -inl.h file. This separates the implementation from the class
definition, while still allowing the implementation to be included where necessary.
Another use of -inl.h files is for definitions of function templates. This can be used to keep your template
definitions easy to read.
Do not forget that a -inl.h file requires a #define guard just like any other header file.
Function Parameter Ordering
When defining a function, parameter order is: inputs, then outputs.
Parameters to C/C++ functions are either input to the function, output from the function, or both. Input parameters
are usually values or const references, while output and input/output parameters will be non-const pointers. 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.
This is not a hard-and-fast rule. Parameters that are both input and output (often classes/structs) muddy the waters,
and, as always, consistency with related functions may require you to bend the rule.
Names and Order of Includes
Use standard order for readability and to avoid hidden dependencies: C library, C++ library, other libraries' .h,
your project's .h.
All of a project's header files should be listed as descentants of the project's source directory without use of UNIX
directory shortcuts . (the current directory) or .. (the parent directory). For example, google-awesome-
project/src/base/logging.h should be included as
#include "base/logging.h"
In dir/foo.cc, whose main purpose is to implement or test the stuff in dir2/foo2.h, order your includes as
follows:
1. dir2/foo2.h (preferred location — see details below).
2. C system files.
3. C++ system files.
4. Other libraries' .h files.
link ▽
link ▽
link ▽
link ▽
5. Your project's .h files.
The preferred ordering reduces hidden dependencies. We want every header file to be compilable on its own. The
easiest way to achieve this is to make sure that every one of them is the first .h file #included in some .cc.
dir/foo.cc and dir2/foo2.h are often in the same directory (e.g. base/basictypes_test.cc and
base/basictypes.h), but can be in different directories too.
Within each section it is nice to order the includes alphabetically.
For example, the includes in google-awesome-project/src/foo/internal/fooserver.cc might look like
this:
#include "foo/public/fooserver.h" // Preferred location.
#include
#include
#include
#include
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"
Scoping
Namespaces
Unnamed namespaces in .cc files are encouraged. With named namespaces, choose the name based on the
project, and possibly its path. Do not use a using-directive.
Definition:
Namespaces subdivide the global scope into distinct, named scopes, and so are useful for preventing name
collisions in the global scope.
Pros:
Namespaces provide a (hierarchical) axis of naming, in addition to the (also hierarchical) name axis provided by
classes.
For example, if two different projects have a class Foo in the global scope, these symbols may collide at compile
time or at runtime. If each project places their code in a namespace, project1::Foo and project2::Foo are
now distinct symbols that do not collide.
Cons:
Namespaces can be confusing, because they provide an additional (hierarchical) axis of naming, in addition to the
(also hierarchical) name axis provided by classes.
Use of unnamed spaces in header files can easily cause violations of the C++ One Definition Rule (ODR).
Decision:
Use namespaces according to the policy described below.
Unnamed Namespaces
l Unnamed namespaces are allowed and even encouraged in .cc files, to avoid runtime naming conflicts:
namespace { // This is in a .cc file.
// The content of a namespace is not indented
enum { kUnused, kEOF, kError }; // Commonly used tokens.
bool AtEof() { return pos_ == kEOF; } // Uses our namespace's EOF.
} // namespace
However, file-scope declarations that are associated with a particular class may be declared in that class as
types, static data members or static member functions rather than as members of an unnamed namespace.
Terminate the unnamed namespace as shown, with a comment // namespace.
l Do not use unnamed namespaces in .h files.
Named Namespaces
Named namespaces should be used as follows:
l Namespaces wrap the entire source file after includes, gflags definitions/declarations, and forward
link ▽
declarations of classes from other namespaces:
// In the .h file
namespace mynamespace {
// All declarations are within the namespace scope.
// Notice the lack of indentation.
class MyClass {
public:
...
void Foo();
};
} // namespace mynamespace
// In the .cc file
namespace mynamespace {
// Definition of functions is within scope of the namespace.
void MyClass::Foo() {
...
}
} // namespace mynamespace
The typical .cc file might have more complex detail, including the need to reference classes in other
namespaces.
#include "a.h"
DEFINE_bool(someflag, false, "dummy flag");
class C; // Forward declaration of class C in the global namespace.
namespace a { class A; } // Forward declaration of a::A.
namespace b {
...code for b... // Code goes against the left margin.
} // namespace b
l Do not declare anything in namespace std, not even forward declarations of standard library classes.
Declaring entities in namespace std is undefined behavior, i.e., not portable. To declare entities from the
standard library, include the appropriate header file.
l You may not use a using-directive to make all names from a namespace available.
// Forbidden -- This pollutes the namespace.
using namespace foo;
l You may use a using-declaration anywhere in a .cc file, and in functions, methods or classes in .h files.
// OK in .cc files.
// Must be in a function, method or class in .h files.
using ::foo::bar;
l Namespace aliases are allowed anywhere in a .cc file, anywhere inside the named namespace that wraps
an entire .h file, and in functions and methods.
// Shorten access to some commonly used names in .cc files.
namespace fbz = ::foo::bar::baz;
// Shorten access to some commonly used names (in a .h file).
namespace librarian {
// The following alias is available to all files including
// this header (in namespace librarian):
// alias names should therefore be chosen consistently
// within a project.
namespace pd_s = ::pipeline_diagnostics::sidetable;
inline void my_inline_function() {
// namespace alias local to a function (or method).
namespace fbz = ::foo::bar::baz;
...
}
} // namespace librarian
Note that an alias in a .h file is visible to everyone #including that file, so public headers (those available
outside a project) and headers transitively #included by them, should avoid defining aliases, as part of the
general goal of keeping public APIs as small as possible.
Nested Classes
Although you may use public nested classes when they are part of an interface, consider a namespace to
keep declarations out of the global scope.
Definition:
A class can define another class within it; this is also called a member class.
class Foo {
private:
// Bar is a member class, nested within Foo.
class Bar {
...
};
};
Pros:
This is useful when the nested (or member) class is only used by the enclosing class; making it a member puts it in
the enclosing class scope rather than polluting the outer scope with the class name. Nested classes can be forward
declared within the enclosing class and then defined in the .cc file to avoid including the nested class definition in
the enclosing class declaration, since the nested class definition is usually only relevant to the implementation.
Cons:
Nested classes can be forward-declared only within the definition of the enclosing class. Thus, any header file
manipulating a Foo::Bar* pointer will have to include the full class declaration for Foo.
Decision:
Do not make nested classes public unless they are actually part of the interface, e.g., a class that holds a set of
options for some method.
Nonmember, Static Member, and Global Functions
Prefer nonmember functions within a namespace or static member functions to global functions; use completely
global functions rarely.
Pros:
Nonmember and static member functions can be useful in some situations. Putting nonmember functions in a
namespace avoids polluting the global namespace.
Cons:
Nonmember and static member functions may make more sense as members of a new class, especially if they
access external resources or have significant dependencies.
Decision:
Sometimes it is useful, or even necessary, to define a 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 namespaces instead.
Functions defined in the same compilation unit as production classes may introduce unnecessary coupling and link-
time dependencies when directly called from other compilation units; static member functions are particularly
susceptible to this. Consider extracting a new class, or placing the functions in a namespace possibly in a separate
library.
If you must define a nonmember function and it is only needed in its .cc file, use an unna