Google C++ Style Guide
Revision 3.260
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
Header Files |
The #define Guard Forward Declarations 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 nullptr/NULL sizeof auto Brace Initialization Boost C++11 unique_ptr |
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 Braced Initializer Lists 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 |
Important Note
Displaying Hidden Details in this Guide link ▽ 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.
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 link ▽ All header files should have #define guards to prevent multiple inclusion. The format of the symbol name should be <PROJECT>_<PATH>_<FILE>_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_
Forward Declarations link ▽ You may forward declare ordinary classes in order to avoid unnecessary #includes.
Definition: A "forward declaration" is a declaration of a class, function, or template without an associated definition. #include lines can often be replaced with forward declarations of whatever symbols are actually used by the client code.
Pros: Unnecessary #includes force the compiler to open more files and process more input. They can also force your code to be recompiled more often, due to changes in the header.
Cons: It can be difficult to determine the correct form of a forward declaration in the presence of features like templates, typedefs, default parameters, and using declarations. It can be difficult to determine whether a forward declaration or a full #include is needed for a given piece of code, particularly when implicit conversion operations are involved. In extreme cases, replacing an #include with a forward declaration can silently change the meaning of code. Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header. Forward declarations of functions and templates can prevent the header owners from making otherwise-compatible changes to their APIs; for example, widening a parameter type, or adding a template parameter with a default value. Forward declaring symbols from namespace std:: usually yields undefined behavior. Structuring code to enable forward declarations (e.g. using pointer members instead of object members) can make the code slower and more complex. The practical efficiency benefits of forward declarations are unproven.
Decision: When using a function declared in a header file, always #include that header. When using a class template, prefer to #include its header file. When using an ordinary class, relying on a forward declaration is OK, but be wary of situations where a forward declaration may be insufficient or incorrect; when in doubt, just #include the appropriate header. Do not replace data members with pointers just to avoid an #include. Always #include the file that actually provides the declarations/definitions you need; do not rely on the symbol being brought in transitively via headers not directly included. One exception is that myfile.cc may rely on #includes and forward declarations from its corresponding header file myfile.h.
Inline Functions 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.