Coding Style of Google.

Google C++ Style Guide

Google C++风格指导

Revision 3.188

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 万岁!”

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.

Google的许多开源项目使用C++作为开发语言。每一个C++程序员均知道:正如一把双刃剑,一方面其提供了许多强大的特性(例如:多态,继承等),另一个方面正是这些强大的特性给程序开发人员带来了无以比拟的复杂性。 这也导致了使用C++编写的项目更加容易出现错误,难以维护等缺点。

PS:诚如许多软件工程师所说那样:也许项目中的bug多寡以及是否易于维护与所采用的语言无多少联系,但一个易于理解,易于使用的工具总会减少我们犯错的机会。一个越复杂的工具,越是容易导致错误, 除非自己对该工具是特别的熟悉且在使用的过程中也特别的小心。因此,一个良好的风格和一个良好的设计就显得格外重要。而此编程风格便是由google众多高手所采用的且在许多项目中得到广泛的采用。

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.

该指导的目的是通过详细阐述在使用C++编程时哪些是值得提倡的做法、哪些是不值得提倡的做法来降低由于其复杂性所带来的那些缺点(难以维护,易于产生错误)。 这些规则保证了你在高效的使用C++的那些特性的同时能够保证代码具有一定的可维护性。

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.

风格,有时候也被称作可读性。其是我们在编写C++程序时所采用且保持的一些惯例。 对于术语“风格”的使用肯能有些用词不当,因为这些惯例不单单仅是源文件所采用那种格式那么简单。

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 canp 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.

本指南涉及的另一个问题是,C + +特性膨胀。C + +是一个有很多高级特性的庞大语言。 在某些特定的情况下,我们限制,甚至禁止某些使用某些特性。我们这么做事为了保证代码的 简洁和避免由此特性所带来的一些不同的常规错误。该指南列出了这些特性并详细的解释了我们为什么限制使用这些特性。

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.

备注:本指南不是C++说明:我们假设你是较为熟练的掌握该门语言。

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.

通常,每个.cc文件都应有一个与其相关联的.h文件。 但也有例外的情况,例如一些单元测试、仅包含main()函数的小规模.cc文件。

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 “卫道士”#define

All header files should have #define guards to prevent multiple inclusion. The format of the symbol name should be <PROJECT>_<PATH>_<FILE>_H_.所有的头文件都应该使用#define 来避免多重包含问题。其格式如下: <项目名称>_<路径>_<文件>_H_.

Header File Dependencies 头文件的依赖性

Don’t use an #include when a forward declaration would suffice.当使用一个向前声明已足够的情况下就不要使用#include

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 reduce 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".

可以通过使用向前声明的方法来显著的减少你自己头文件所需要包含的头文件数量。 例如,如果你的头文件要使用File类,而File类无需访问 File 类的声明,则你的头文件可以仅用一个向前声明class File;,而非 使用#include "file/base/file.h"

How can we use a class Foo in a header file without access to its definition?

我们怎样在不访问Foo类的定义情况下使用Foo类呢?

  • We can declare data members of type Foo* or Foo&.我们可以一些声明Foo* 或者Foo&类型的数据成员
  • 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.)我们可以声明(但不定义)一些带有Foo类型的参数的函数且/或者带有Foo类型的返回值。 (一个例外是:当一个具有一个非明确、一个参数的构造函数Foo或者const Foo&类型的参数时, 这使得我们需要一个完整的定义来支持类型的自动转换。 )
  • We can declare static data members of type Foo. This is because static data members are defined outside the class definition.我们可以声明一些Foo类型的静态数据成员。因为静态数据成员是在类定义之外被定义的。

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.

另一方面,如果你类的派生子类Foo或者具有Foo 类型的数据成员,你就必须包含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.

有时候,使用指针而不是使用成员对象是有些道理的(或者可能更好,scoped_ptr)。 然而,这些会使代码的可读性负责化且会导致性能流失,因此如果仅仅是为了减少包含头文件的数量, 那么应该避免此中变换。

Of course, .cc files typically do require the definitions of the classes they use, and usually have to include several header files.

当然, .cc文件通常需要他们所使用类的定义且通常需要包含一系列的头文件。

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 inmyfile.h, instead of myfile.cc.

如果在源文件中使用Foo ,你应当包含 Foo 的定义或者 通过#include或者通过一个向前声明为Foo提供定义。不要仅依赖于变量通过头文件而非直接的包含来临时性的引入。 一个例外是如果Foo被用在myfile.cc文件中,那么可以通过使用#include来包含 在 myfile.h而非myfile.cc文件来引入Foo

Inline Functions 内联函数

Define functions inline only when they are small, say, 10 lines or less.仅当函数是非常小的时候,仅10行代码或者更少的时候我们将该函数定义为内联函数

The -inl.h Files

You may use file names with a -inl.h suffix to define complex inline functions when needed.

Function Parameter Ordering

When defining a function, parameter order is: inputs, then outputs.

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.

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.

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.

Nonmember, Static Member, and Global Functions

Prefer nonmember functions within a namespace or static member functions to global functions; use completely global functions rarely.

Local Variables

Place a function’s variables in the narrowest scope possible, and initialize variables in the declaration.

Static and Global Variables

Static or global variables of class type are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction.

Classes

Classes are the fundamental unit of code in C++. Naturally, we use them extensively. This section lists the main dos and don’ts you should follow when writing a class.

Doing Work in Constructors

In general, constructors should merely set member variables to their initial values. Any complex initialization should go in an explicit Init() method.

Default Constructors

You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.

Explicit Constructors

Use the C++ keyword explicit for constructors with one argument.

Copy Constructors

Provide a copy constructor and assignment operator only when necessary. Otherwise, disable them with DISALLOW_COPY_AND_ASSIGN.

Structs vs. Classes

Use a struct only for passive objects that carry data; everything else is a class.

Inheritance

Composition is often more appropriate than inheritance. When using inheritance, make it public.

Multiple Inheritance

Only very rarely is multiple implementation inheritance actually useful. We allow multiple inheritance only when at most one of the base classes has an implementation; all other base classes must be pure interface classes tagged with the Interface suffix.

Interfaces

Classes that satisfy certain conditions are allowed, but not required, to end with an Interface suffix.

Operator Overloading

Do not overload operators except in rare, special circumstances.

Access Control

Make data members private, and provide access to them through accessor functions as needed (for technical reasons, we allow data members of a test fixture class to beprotected when using Google Test). Typically a variable would be called foo_ and the accessor function foo(). You may also want a mutator function set_foo(). Exception:static const data members (typically called kFoo) need not be private.

Declaration Order

Use the specified order of declarations within a class: public: before private:, methods before data members (variables), etc.

Write Short Functions

Prefer small and focused functions.

Google-Specific Magic

There are various tricks and utilities that we use to make C++ code more robust, and various ways we use C++ that may differ from what you see elsewhere.

Smart Pointers

If you actually need pointer semantics, scoped_ptr is great. You should only use std::tr1::shared_ptr with a non-const referent when it is truly necessary to share ownership of an object (e.g. inside an STL container). You should never use auto_ptr.

cpplint

Use cpplint.py to detect style errors.

Other C++ Features

Reference Arguments

All parameters passed by reference must be labeled const.

Function Overloading

Use overloaded functions (including constructors) only if a reader looking at a call site can get a good idea of what is happening without having to first figure out exactly which overload is being called.

Default Arguments

We do not allow default function parameters, except in a few uncommon situations explained below.

Variable-Length Arrays and alloca()

We do not allow variable-length arrays or alloca().

Friends

We allow use of friend classes and functions, within reason.

Exceptions

We do not use C++ exceptions.

Run-Time Type Information (RTTI)

We do not use Run Time Type Information (RTTI).

Casting

Use C++ casts like static_cast<>(). Do not use other cast formats like int y = (int)x; or int y = int(x);.

Streams

Use streams only for logging.

Preincrement and Predecrement

Use prefix form (++i) of the increment and decrement operators with iterators and other template objects.

Use of const

We strongly recommend that you use const whenever it makes sense to do so.

Integer Types

Of the built-in C++ integer types, the only one used is int. If a program needs a variable of a different size, use a precise-width integer type from <stdint.h>, such asint16_t.

64-bit Portability

Code should be 64-bit and 32-bit friendly. Bear in mind problems of printing, comparisons, and structure alignment.

Preprocessor Macros

Be very cautious with macros. Prefer inline functions, enums, and const variables to macros.

0 and NULL

Use 0 for integers, 0.0 for reals, NULL for pointers, and '\0' for chars.

sizeof

Use sizeof(varname) instead of sizeof(type) whenever possible.

Boost

Use only approved libraries from the Boost library collection.

C++0x

Use only approved libraries and language extensions from C++0x. Currently, none are approved.

Naming

The most important consistency rules are those that govern naming. The style of a name immediately informs us what sort of thing the named entity is: a type, a variable, a function, a constant, a macro, etc., without requiring us to search for the declaration of that entity. The pattern-matching engine in our brains relies a great deal on these naming rules.

Naming rules are pretty arbitrary, but we feel that consistency is more important than individual preferences in this area, so regardless of whether you find them sensible or not, the rules are the rules.

General Naming Rules

Function names, variable names, and filenames should be descriptive; eschew abbreviation. Types and variables should be nouns, while functions should be “command” verbs.

File Names

Filenames should be all lowercase and can include underscores (_) or dashes (-). Follow the convention that your project uses. If there is no consistent local pattern to follow, prefer “_”.

Type Names

Type names start with a capital letter and have a capital letter for each new word, with no underscores: MyExcitingClass, MyExcitingEnum.

Variable Names

Variable names are all lowercase, with underscores between words. Class member variables have trailing underscores. For instance: my_exciting_local_variable,my_exciting_member_variable_.

Constant Names

Use a k followed by mixed case: kDaysInAWeek.

Function Names

Regular functions have mixed case; accessors and mutators match the name of the variable: MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(),set_my_exciting_member_variable().

Namespace Names

Namespace names are all lower-case, and based on project names and possibly their directory structure: google_awesome_project.

Enumerator Names

Enumerators should be named either like constants or like macros: either kEnumName or ENUM_NAME.

Macro Names

You’re not really going to define a macro, are you? If you do, they’re like this: MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

Exceptions to Naming Rules

If you are naming something that is analogous to an existing C or C++ entity then you can follow the existing naming convention scheme.

Comments

Though a pain to write, comments are absolutely vital to keeping our code readable. The following rules describe what you should comment and where. But remember: while comments are very important, the best code is self-documenting. Giving sensible names to types and variables is much better than using obscure names that you must then explain through comments.

When writing your comments, write for your audience: the next contributor who will need to understand your code. Be generous — the next one may be you!

Comment Style

Use either the // or /* */ syntax, as long as you are consistent.

File Comments

Start each file with a copyright notice, followed by a description of the contents of the file.

Class Comments

Every class definition should have an accompanying comment that describes what it is for and how it should be used.

Function Comments

Declaration comments describe use of the function; comments at the definition of a function describe operation.

Variable Comments

In general the actual name of the variable should be descriptive enough to give a good idea of what the variable is used for. In certain cases, more comments are required.

Implementation Comments

In your implementation you should have comments in tricky, non-obvious, interesting, or important parts of your code.

Punctuation, Spelling and Grammar

Pay attention to punctuation, spelling, and grammar; it is easier to read well-written comments than badly written ones.

TODO Comments

Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.

Deprecation Comments

Mark deprecated interface points with DEPRECATED comments.

Formatting

Coding style and formatting are pretty arbitrary, but a project is much easier to follow if everyone uses the same style. Individuals may not agree with every aspect of the formatting rules, and some of the rules may take some getting used to, but it is important that all project contributors follow the style rules so that they can all read and understand everyone’s code easily.

To help you format code correctly, we’ve created a settings file for emacs.

Line Length

Each line of text in your code should be at most 80 characters long.

Non-ASCII Characters

Non-ASCII characters should be rare, and must use UTF-8 formatting.

Spaces vs. Tabs

Use only spaces, and indent 2 spaces at a time.

Function Declarations and Definitions

Return type on the same line as function name, parameters on the same line if they fit.

Function Calls

On one line if it fits; otherwise, wrap arguments at the parenthesis.

Conditionals

Prefer no spaces inside parentheses. The else keyword belongs on a new line.

Loops and Switch Statements

Switch statements may use braces for blocks. Empty loop bodies should use {} or continue.

Pointer and Reference Expressions

No spaces around period or arrow. Pointer operators do not have trailing spaces.

Boolean Expressions

When you have a boolean expression that is longer than the standard line length, be consistent in how you break up the lines.

Return Values

Do not needlessly surround the return expression with parentheses.

Variable and Array Initialization

Your choice of = or ().

Preprocessor Directives

The hash mark that starts a preprocessor directive should always be at the beginning of the line.

Class Format

Sections in public, protected and private order, each indented one space.

Constructor Initializer Lists

Constructor initializer lists can be all on one line or with subsequent lines indented four spaces.

Namespace Formatting

The contents of namespaces are not indented.

Horizontal Whitespace

Use of horizontal whitespace depends on location. Never put trailing whitespace at the end of a line.

Vertical Whitespace

Minimize use of vertical whitespace.

Exceptions to the Rules

The coding conventions described above are mandatory. However, like all good rules, these sometimes have exceptions, which we discuss here.

Existing Non-conformant Code

You may diverge from the rules when dealing with code that does not conform to this style guide.

Windows Code

link

Windows programmers have developed their own set of coding conventions, mainly derived from the conventions in Windows headers and other Microsoft code. We want to make it easy for anyone to understand your code, so we have a single set of guidelines for everyone writing C++ on any platform.

It is worth reiterating a few of the guidelines that you might forget if you are used to the prevalent Windows style:

  • Do not use Hungarian notation (for example, naming an integer iNum). Use the Google naming conventions, including the .cc extension for source files.
  • Windows defines many of its own synonyms for primitive types, such as DWORD, HANDLE, etc. It is perfectly acceptable, and encouraged, that you use these types when calling Windows API functions. Even so, keep as close as you can to the underlying C++ types. For example, use const TCHAR * instead of LPCTSTR.
  • When compiling with Microsoft Visual C++, set the compiler to warning level 3 or higher, and treat all warnings as errors.
  • Do not use #pragma once; instead use the standard Google include guards. The path in the include guards should be relative to the top of your project tree.
  • In fact, do not use any nonstandard extensions, like #pragma and __declspec, unless you absolutely must. Using __declspec(dllimport) and __declspec(dllexport) is allowed; however, you must use them through macros such as DLLIMPORT and DLLEXPORT, so that someone can easily disable the extensions if they share the code.

However, there are just a few rules that we occasionally need to break on Windows:

  • Normally we forbid the use of multiple implementation inheritance; however, it is required when using COM and some ATL/WTL classes. You may use multiple implementation inheritance to implement COM or ATL/WTL classes and interfaces.
  • Although you should not use exceptions in your own code, they are used extensively in the ATL and some STLs, including the one that comes with Visual C++. When using the ATL, you should define _ATL_NO_EXCEPTIONS to disable exceptions. You should investigate whether you can also disable exceptions in your STL, but if not, it is OK to turn on exceptions in the compiler. (Note that this is only to get the STL to compile. You should still not write exception handling code yourself.)
  • The usual way of working with precompiled headers is to include a header file at the top of each source file, typically with a name like StdAfx.h or precompile.h. To make your code easier to share with other projects, avoid including this file explicitly (except in precompile.cc), and use the /FI compiler option to include the file automatically.
  • Resource headers, which are usually named resource.h and contain only macros, do not need to conform to these style guidelines.

Parting Words

Use common sense and BE CONSISTENT.

If you are editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around their if clauses, you should, too. If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too.

The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you are saying, rather than on how you are saying it. We present global style rules here so people know the vocabulary. But local style is also important. If code you add to a file looks drastically different from the existing code around it, the discontinuity throws readers out of their rhythm when they go to read it. Try to avoid this.

OK, enough writing about writing code; the code itself is much more interesting. Have fun!


Revision 3.188

Benjy Weinberger
Craig Silverstein
Gregory Eitzmann
Mark Mentovai
Tashana Landray