1. 程式人生 > >Google C++ Style Guide中英對照(三)

Google C++ Style Guide中英對照(三)

1 Naming 命名規則

The mostimportant consistency rules are those that govern naming. The style of a nameimmediately informs us what sort of thing the named entity is: a type, avariable, a function, a constant, a macro, etc., without requiring us to searchfor the declaration of that entity. The pattern-matching engine in our brainsrelies a great deal on these naming rules.

最重要的一致性規則是命名管理。命名的風格能立刻告訴我們這個名字代表的實體到底是什麼東西:型別,變數,函式,常量,巨集,等等,而不需要我們去尋找該實體的宣告。我們頭腦中的模式匹配引擎大量依賴於這些命名規則。

Naming rules arepretty arbitrary, but we feel that consistency is more important thanindividual preferences in this area, so regardless of whether you find themsensible or not, the rules are the rules.

命名規則是很隨意的,但我們覺得這方面一致性要比個人喜好重要得多,所以不管你怎麼想,規則就是規則。

Function names,variable names, and filenames should be descriptive; eschew abbreviation. Typesand variables should be nouns, while functions should be "command"verbs.

函式名,變數名,和檔名應該是描述性的;不要過度縮寫。型別名和變數名應該是名詞,而函式名應該是命令式的動詞。

How to Name 怎麼命名

Give asdescriptive a name as possible, within reason. Do not worry about savinghorizontal space as it is far more important to make your code immediatelyunderstandable by a new reader. Examples of well-chosen names:

儘量有理由的起一個描述性的名字。別擔心行空間的問題[f1] ,讓你的程式碼能被新讀者很快理解遠遠比這更重要。好的例子:

int num_errors;                  // Good.

int num_completed_connections;   // Good.

Poorly-chosennames use ambiguous abbreviations or arbitrary characters that do not conveymeaning:

不好的名字使用模稜兩可的縮寫或難以傳達其含義的任意字元:

int n;                           // Bad - meaningless.無含義

int nerr;                        // Bad - ambiguousabbreviation.模糊的縮寫

int n_comp_conns;                // Bad - ambiguousabbreviation.模糊的縮寫

Type andvariable names should typically be nouns: e.g., FileOpener, num_errors.

型別名和變數名通常應該是名詞:如FileOpener,num_errors。

Function namesshould typically be imperative (that is they should be commands): e.g.,OpenFile(), set_num_errors(). There is an exception for accessors, which,described more completely in Function Names, should be named the same as thevariable they access.

函式名通常應該是祈使語氣的(即命令性的):如OpenFile(),set_num_errors()。取值函式[f2] 是個特例,函式名應該與變數名相同,這樣函式名的含義更完整。

Abbreviations 縮寫

Do not useabbreviations unless they are extremely well known outside your project. Forexample:

不要使用縮寫,除非這個縮寫在你的專案之外也被廣泛使用。例如:

// Good

// These show proper names with noabbreviations.

int num_dns_connections;  // Most people know what "DNS"stands for.

int price_count_reader;   // OK, price count. Makes sense.

// Bad!

// Abbreviations can be confusing orambiguous outside a small group.

int wgc_connections;  // Only your group knows what this standsfor.

int pc_reader;        // Lots of things can be abbreviated"pc".

Never abbreviateby leaving out letters:

永遠不要用省略字母的縮寫。

int error_count;  // Good.

int error_cnt;    // Bad.

Filenames shouldbe all lowercase and can include underscores (_) or dashes (-). Follow theconvention that your project uses. If there is no consistent local pattern tofollow, prefer "_".

檔名應該全都用小寫,中間用“-”或“_”當分隔符。根據你的專案的慣例。如果沒有固定的習慣的話,推薦用“_”。

Examples ofacceptable file names:

可接受的檔名示例:

my_useful_class.cc

my-useful-class.cc

myusefulclass.cc

myusefulclass_test.cc // _unittest and_regtest are deprecated.這兩個字尾不建議使用了。

C++ files shouldend in .cc and header files should end in .h.

C++檔案應該以.cc結尾,標頭檔案以.h結尾。

Do not usefilenames that already exist in /usr/include, such as db.h.

不要用系統標頭檔案中已經存在的名字,如db.h。

In general, makeyour filenames very specific. For example, use http_server_logs.h rather thanlogs.h. A very common case is to have a pair of files called, e.g., foo_bar.hand foo_bar.cc, defining a class called FooBar.

通常來說,讓你的檔名非常的具體。例如用http_server_logs.h就比logs.h更好。定義類時檔名經常成對出現,如foo_bar.h和foo_bar.cc,對應類FooBar。

Inline functionsmust be in a .h file. If your inline functions are very short, they should godirectly into your .h file. However, if your inline functions include a lot ofcode, they may go into a third file that ends in -inl.h. In a class with a lotof inline code, your class could have three files:

行內函數必須放在.h檔案中。如果行內函數很短,就直接放進.h檔案中。否則就應該放進-inl.h檔案中。一個有著很多內聯程式碼的類,可以對應三個檔案:

url_table.h      // The class declaration.類的宣告

url_table.cc     // The class definition.類的定義

url_table-inl.h  // Inline functions that include lots ofcode.程式碼較多的行內函數的定義

See also thesection -inl.h Files

Type names startwith a capital letter and have a capital letter for each new word, with nounderscores: MyExcitingClass, MyExcitingEnum.

型別名以大寫字母開頭,且其中每個詞第一個字母都大寫,不用下劃線:MyExcitingClass,MyExcitingEnum。

The names of alltypes — classes, structs, typedefs, and enums — have the same namingconvention. Type names should start with a capital letter and have a capitalletter for each new word. No underscores. For example:

所有型別——類,結構體,自定義型別,和列舉——都有著相同的命名慣例。型別名以大寫字母開頭,且其中每個詞也都以大寫字母開頭。不用下劃線。例如:

// classes and structs

class UrlTable { ...

class UrlTableTester { ...

struct UrlTableProperties { ...

// typedefs

typedef hash_map<UrlTableProperties *,string> PropertiesMap;

// enums

enum UrlTableErrors { ...

Variable namesare all lowercase, with underscores between words. Class member variables havetrailing underscores. For instance: my_exciting_local_variable,my_exciting_member_variable_.

變數名都是小寫的,每個詞之間用下劃線連線。類的成員變數名結尾有個下劃線。例如:my_exciting_local_varialbe;my_exciting_member_variable_。

Common Variable names 普通變數名

For example:

例如:

string table_name;  // OK - uses underscore.

string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.

Class Data Members類的資料成員

Data members(also called instance variables or member variables) are lowercase with optionalunderscores like regular variable names, but always end with a trailingunderscore.

資料成員(也被稱為例項變數或成員變數)的名字都是小寫的,可以像通常的變數名一樣帶下劃線,但結尾總要有個下劃線。

string table_name_;  // OK - underscore at end.

string tablename_;   // OK.

Struct Variables 結構體變數

Data members instructs should be named like regular variables without the trailing underscoresthat data members in classes have.

結構體中的資料成員要像常規變數那麼命名,結尾不像類的資料成員那樣有下劃線。

struct UrlTableProperties {

 string name;

  intnum_entries;

}

See Structs vs.Classes for a discussion of when to use a struct versus a class.

Global Variables 全域性變數

There are nospecial requirements for global variables, which should be rare in any case,but if you use one, consider prefixing it with g_ or some other marker toeasily distinguish it from local variables.

對於全域性變數沒有特別要求,少用就好,但如果你要用,考慮加個g_字首,或其它能很容易的區分全域性變數與區域性變數的標記。

Use a k followedby mixed case: kDaysInAWeek.

在名稱前加k,其後與變數相同:kDaysInAWeek。

All compile-timeconstants, whether they are declared locally, globally, or as part of a class,follow a slightly different naming convention from other variables. Use a kfollowed by words with uppercase first letters:

所有的編譯期變數,不管是區域性變數,全域性變數,還是類的一部分,都要遵守一個與其它變數不同的慣例。在名稱前加k,後面接第一個字母大寫的各個單詞:

const int kDaysInAWeek = 7;

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

常規函式的名字大小寫混合;取值和設值函式要與對應的變數名匹配:MyExcitingFunction(),MyExcitingMethod(),my_exciting_member_variable(),set_my_exciting_member_variable()。

Regular Functions 常規函式

Functions shouldstart with a capital letter and have a capital letter for each new word. Nounderscores.

函式名中每個單詞首字母都大寫。沒有下劃線。

If your functioncrashes upon an error, you should append OrDie to the function name. This onlyapplies to functions which could be used by production code and to errors thatare reasonably likely to occur during normal operation.

如果你的函式可能出現錯誤,你應該在函式名後面加上OrDie。這隻適用於能用於生產[f3] ,且在正常操作中可能會發生有原因的錯誤的函式上。

AddTableEntry()

DeleteUrl()

OpenFileOrDie()

Accessors and Mutators 取值和設值函式

Accessors andmutators (get and set functions) should match the name of the variable they aregetting and setting. This shows an excerpt of a class whose instance variableis num_entries_.

取值和設值函式應該與相關的變數名匹配。這裡摘錄一個有著名為num_entries_的成員的類。

class MyClass {

 public:

  ...

  intnum_entries() const { return num_entries_; }

  voidset_num_entries(int num_entries) { num_entries_ = num_entries; }

 private:

  intnum_entries_;

};

You may also uselowercase letters for other very short inlined functions. For example if afunction were so cheap you would not cache the value if you were calling it ina loop, then lowercase naming would be acceptable.

其它的一些非常短的行內函數也可以全用小寫。例如,如果一個函式的開銷小到了你在迴圈中呼叫它都不需要將結果快取起來的話,用小寫的名字就很合適了。

Namespace namesare all lower-case, and based on project names and possibly their directorystructure: google_awesome_project.

名稱空間的名字都是小寫的,與專案名,可能還包括目錄結構,相關。

See Namespacesfor a discussion of namespaces and how to name them.

Enumeratorsshould be named either like constants or like macros: either kEnumName orENUM_NAME.

列舉的命名應當和常量或巨集一致:kEnumName或是ENUM_NAME。

Preferably, theindividual enumerators should be named like constants. However, it is alsoacceptable to name them like macros. The enumeration name, UrlTableErrors (andAlternateUrlTableErrors), is a type, and therefore mixed case.

單獨的列舉應該優先採用常量的命名方式。但巨集方式的命名也可以接受。列舉名,UrlTableErrors (和 AlternateUrlTableErrors),是型別,因此要大小寫混合。

enum UrlTableErrors {

  kOK= 0,

 kErrorOutOfMemory,

 kErrorMalformedInput,

};

enum AlternateUrlTableErrors {

  OK =0,

 OUT_OF_MEMORY = 1,

 MALFORMED_INPUT = 2,

};

Until January2009, the style was to name enum values like macros. This caused problems withname collisions between enum values and macros. Hence, the change to preferconstant-style naming was put in place. New code should prefer constant-stylenaming if possible. However, there is no reason to change old code to useconstant-style names, unless the old names are actually causing a compile-timeproblem.

2009年1月前,我們的建議是列舉名的風格和巨集一致。這導致了一些列舉與巨集的命名衝突。因此,現在改為採用常量風格的命名。新程式碼應該儘量採用常量風格。但也不必將舊程式碼改成常量風格的,除非舊的名字確實會導致編譯錯誤。

You're notreally going to define a macro, are you? If you do, they're like this:MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

你不會真的要定義巨集吧?非得用巨集的話,要這麼命名:MY_MACRO_THAT_SCARES_SMALL_CHILDREN。

Please see thedescription of macros; in general macros should not be used. However, if theyare absolutely needed, then they should be named with all capitals andunderscores.

請看巨集的描述;通常不該用巨集。但是,如果真的需要巨集,巨集名應該全是大寫,詞之前用下劃線分隔。

#define ROUND(x) ...

#define PI_ROUNDED 3.0

If you arenaming something that is analogous to an existing C or C++ entity then you canfollow the existing naming convention scheme.

如果你命名的實體與已有C/C++實體類似,可參考現有命名策略。

bigopen()

    function name, follows form of open() 函式名,參考open()

uint

    typedef 自定義型別

bigpos

    struct or class, follows form of pos 結構體或類,參考pos

sparse_hash_map

    STL-like entity; follows STL namingconventions STL風格實體;參考STL命名慣例

LONGLONG_MAX

    a constant, as in INT_MAX 常量,參考INT_MAX

2 Comments 註釋

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

註釋儘管寫起來很痛苦,但在保持程式碼的可讀性方面至關重要。下面的規則描述了你應該在哪註釋什麼。但要記住:註釋很重要,但最好的程式碼本身就是文件。給型別和變數起有意義的名字要比用難懂的名字導致必須得用註釋解釋強得多。

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

在寫註釋時,目標是你的觀眾:下一個需要看懂你程式碼的作者。要好好寫[f4] ——下一個作者可能就是你!

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

用//和/**/都行,儘量保持一致就行。

You can useeither the // or the /* */ syntax; however, // is much more common. Beconsistent with how you comment and what style you use where.

你既可以用//也可以用/**/;但//更常用。保持註釋風格和註釋位置與內容的一致性。

Start each filewith license boilerplate, followed by a description of its contents.

每個檔案的開始是版權公告,其後是檔案內容描述。

Legal Notice and Author Line 法律宣告和作者資訊

Every fileshould contain license boilerplate. Choose the appropriate boilerplate for thelicense used by the project (for example, Apache 2.0, BSD, LGPL, GPL).

每個檔案都應包括許可證資訊。為專案選擇適合的許可證版本(如Apache2.0、BSD、LGPL、GPL)。

If you makesignificant changes to a file with an author line, consider deleting the authorline.

如果你對一個有作者資訊的檔案進行了大修改,考慮刪掉作者資訊。

File Contents 檔案內容

Every fileshould have a comment at the top describing its contents.

每個檔案都應在開頭用註釋描述檔案內容。

Generally a .hfile will describe the classes that are declared in the file with an overviewof what they are for and how they are used. A .cc file should contain moreinformation about implementation details or discussions of tricky algorithms.If you feel the implementation details or a discussion of the algorithms wouldbe useful for someone reading the .h, feel free to put it there instead, butmention in the .cc that the documentation is in the .h file.

通常來說.h檔案會描述檔案內宣告的類的用途和用法。.cc檔案應該包括更多關於實現細節或演算法細節討論等資訊。如果你覺得實現細節或演算法細節討論會對閱讀.h檔案的人有幫助,就可以將這些描述放到.h檔案裡,但要在.cc中註明文件在.h檔案中。

Do not duplicatecomments in both the .h and the .cc. Duplicated comments diverge.

不要在.h和.cc中重複註釋。這種做法偏離了註釋的意義。

Every classdefinition should have an accompanying comment that describes what it is forand how it should be used.

每個類定義都應伴隨著描述用途和用法的註釋。

// Iterates over the contents of aGargantuanTable.  Sample usage:

//   GargantuanTableIterator* iter = table->NewIterator();

//   for (iter->Seek("foo"); !iter->done(); iter->Next()){

//     process(iter->key(), iter->value());

//   }

//   delete iter;

class GargantuanTableIterator {

  ...

};

If you havealready described a class in detail in the comments at the top of your filefeel free to simply state "See comment at top of file for a completedescription", but be sure to have some sort of comment.

如果你已經在檔案開頭描述了類的細節,可以簡單的標註“見檔案開頭的完整描述”,但務必確保確實有這類註釋。

Document thesynchronization assumptions the class makes, if any. If an instance of theclass can be accessed by multiple threads, take extra care to document therules and invariants surrounding multithreaded use.

如果類有任何同步前提,要文件說明。如果類的例項需要在多執行緒環境下被訪問,要特別注意文件說明多執行緒使用中的規則和常量使用。

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

宣告處的註釋描述了函式的用途;定義處的註釋描述了具體的操作。

Function Declarations 函式宣告

Every functiondeclaration should have comments immediately preceding it that describe whatthe function does and how to use it. These comments should be descriptive("Opens the file") rather than imperative ("Open thefile"); the comment describes the function, it does not tell the functionwhat to do. In general, these comments do not describe how the functionperforms its task. Instead, that should be left to comments in the functiondefinition.

每個函式宣告前面都應有註釋來描述函式的用途和用法。這些註釋應該是敘述性的(“打開了檔案”)而不是命令式的(“開啟檔案”);註釋是描述函式的,而不是命令函式去做什麼。通常這些註釋不會描述函式如何工作的,這些內容留給函式定義處的註釋去做。

Types of thingsto mention in comments at the function declaration:

1.    What the inputs and outputsare.

2.    For class member functions:whether the object remembers reference arguments beyond the duration of themethod call, and whether it will free them or not.

3.    If the function allocatesmemory that the caller must free.

4.    Whether any of the argumentscan be a null pointer.

5.    If there are any performanceimplications of how a function is used.

6.    If the function is re-entrant.What are its synchronization assumptions?

在函式宣告處註釋要提及的事物:

1.    輸入和輸出是什麼。

2.    對於類的成員函式:在函式呼叫之外物件是否保持對引數的引用,是否會釋放這種引用。

3.    函式是否進行了呼叫者必須釋放的記憶體分配。

4.    函式的引數可不可以是空指標。

5.    函式的使用方法上有沒有效能隱患。

6.    如果函式是可重入的,其同步前提是什麼?

Here is anexample:

這裡有個例子:

// Returns an iterator for this table.  It is the client's

// responsibility to delete the iteratorwhen it is done with it,

// and it must not use the iterator once theGargantuanTable object

// on which the iterator was created hasbeen deleted.

//

// The iterator is initially positioned atthe beginning of the table.

//

// This method is equivalent to:

//   Iterator* iter = table->NewIterator();

//   iter->Seek("");

//   return iter;

// If you are going to immediately seek toanother place in the

// returned iterator, it will be faster touse NewIterator()

// and avoid the extra seek.

Iterator* GetIterator() const;

However, do notbe unnecessarily verbose or state the completely obvious. Notice below that itis not necessary to say "returns false otherwise" because this isimplied.

但不必太囉嗦,或做些顯而易見的說明。注意下面的註釋沒有必要加上“returns false otherwise “,因為這是顯然的。

// Returns true if the table cannot hold anymore entries.

bool IsTableFull();

When commentingconstructors and destructors, remember that the person reading your code knowswhat constructors and destructors are for, so comments that just say somethinglike "destroys this object" are not useful. Document whatconstructors do with their arguments (for example, if they take ownership ofpointers), and what cleanup the destructor does. If this is trivial, just skipthe comment. It is quite common for destructors not to have a header comment.

在註釋建構函式和解構函式時,記住看你程式碼的人知道什麼是建構函式什麼是解構函式,所以如“會銷燬此物件“之類的註釋都是廢話。文件中要說明建構函式對引數做了什麼(例如是否取得指標所有權),和解構函式都清理了什麼。如果這些都無關緊要,就省略註釋。解構函式沒有頭註釋是很常見的。

Function Definitions 函式定義

Each functiondefinition should have a comment describing what the function does if there'sanything tricky about how it does its job. For example, in the definitioncomment you might describe any coding tricks you use, give an overview of thesteps you go through, or explain why you chose to implement the function in theway you did rather than using a viable alternative. For instance, you mightmention why it must acquire a lock for the first half of the function but why itis not needed for the second half.

每個函式定義處都應該有註釋描述函式功能和實現要點。例如你用的程式設計技巧,實現的大致步驟,或解釋為什麼你用這種方法實現這個函式而不是用另一種方法。例如你可以提一下為什麼函式的前一半需要鎖而後一半不需要。

Note you shouldnot just repeat the comments given with the function declaration, in the .hfile or wherever. It's okay to recapitulate briefly what the function does, butthe focus of the comments should be on how it does it.

要注意你不能只是重複函式宣告處的註釋。可以簡短的概述一下函式做了什麼,但註釋的目的是要說明它是怎麼做的。

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

通常變數的名字就應該足夠描述清楚變數的用途的了。在某些場合時,也需要額外的註釋。

Class Data Members 類資料成員

Each class datamember (also called an instance variable or member variable) should have acomment describing what it is used for. If the variable can take sentinelvalues with special meanings, such as a null pointer or -1, document this. Forexample:

每個類的資料成員(也被稱為例項變數或成員變數)應該有描述其用途的註釋。如果這個變數可以取到有特殊含義的值,如空指標或-1,要文件說明。例如:

private:

 //Keeps track of the total number of entries in the table.

 //Used to ensure we do not go over the limit. -1 means

 //that we don't yet know how many entries the table has.

 intnum_total_entries_;

Global Variables 全域性變數

As with datamembers, all global variables should have a comment describing what they areand what they are used for. For example:

與資料成員一樣,所有的全域性變數都應該用註釋來描述變數的含義和用途。例如:

// The total number of tests cases that we runthrough in this regression test.

const int kNumTestCases = 6;

In yourimplementation you should have comments in tricky, non-obvious, interesting, orimportant parts of your code.

對於程式碼中巧妙的、晦澀的、有趣的、或重要的部分,應用註釋說明。

Class Data Members 類資料成員

Tricky orcomplicated code blocks should have comments before them. Example:

巧妙的或複雜的程式碼段應該在前面註釋。例如:

// Divide result by two, taking into accountthat x

// contains the carry from the add.

for (int i = 0; i < result->size();i++) {

  x =(x << 8) + (*result)[i];

 (*result)[i] = x >> 1;

  x&= 1;

}

Line Comments 行註釋

Also, lines thatare non-obvious should get a comment at the end of the line. These end-of-linecomments should be separated from the code by 2 spaces. Example:

同樣的,含義不明的行應該在行尾註釋。這些行尾的註釋應該與程式碼保持2個空格的間隙。如:

// If we have enough memory, mmap the dataportion too.

mmap_budget = max<int64>(0,mmap_budget - index_->length());

if (mmap_budget >= data_size_ &&!MmapData(mmap_chunk_bytes, mlock))

 return;  // Error already logged.

Note that thereare both comments that describe what the code is doing, and comments thatmention that an error has already been logged when the function returns.

注意到有兩條註釋,一條描述了程式碼在做什麼,另一條提到了在函式因為錯誤而返回時錯誤已經被記錄在日誌中了。

If you haveseveral comments on subsequent lines, it can often be more readable to linethem up:

如果你需要連續進行多行註釋,可以使之對齊獲得更好的可讀性:

DoSomething();                  // Comment here so thecomments line up.

DoSomethingElseThatIsLonger();  // Comment here so there are two spacesbetween

                                // the code and the comment.

{ // One space before comment when opening anew scope is allowed,

  //thus the comment lines up with the following comments and code.

 DoSomethingElse();  // Two spacesbefore line comments normally.

}

nullptr/NULL, true/false, 1, 2, 3... 直接量

When you pass ina null pointer, boolean, or literal integer values to functions, you shouldconsider adding a comment about what they are, or make your codeself-documenting by using constants. For example, compare:

當你向函式傳遞了一個空指標,布林量,或直接量時,應考慮增加一個註釋說明它們是什麼,或用常量來讓你的程式碼自文件化。例如,比如:

bool success =CalculateSomething(interesting_value,

                                  10,

                                  false,

                                  NULL);  // What are these arguments??

versus:

與:

bool success =CalculateSomething(interesting_value,

                                  10,     // Default base value.

                                  false,  // Not the first time we're calling this.

                                  NULL);  // No callback.

Oralternatively, constants or self-describing variables:

或者用常量或自描述型的變數:

const int kDefaultBaseValue = 10;

const bool kFirstTimeCalling = false;

Callback *null_callback = NULL;

bool success =CalculateSomething(interesting_value,

                                 kDefaultBaseValue,

                                 kFirstTimeCalling,

                                 null_callback);

Don'ts 不要做的事

Note that youshould never describe the code itself. Assume that the person reading the codeknows C++ better than you do, even though he or she does not know what you aretrying to do:

要注意你永遠都不該自然語言翻譯程式碼。要假設看你程式碼的人比你更懂C++,即便他或她不知道你的用意:

// Now go through the b array and make surethat if i occurs,

// the next element is i+1.

...       // Geez.  What a useless comment.

Pay attention topunctuation, spelling, and grammar; it is easier to read well-written commentsthan badly written ones.

要注意標點、拼寫和語法;寫的好的註釋要比寫的差的更容易閱讀。

Comments shouldbe as readable as narrative text, with proper capitalization and punctuation.In many cases, complete sentences are more readable than sentence fragments.Shorter comments, such as comments at the end of a line of code, can sometimesbe less formal, but you should be consistent with your style.

註釋應該和敘事文字一樣可讀,有著適當的大小寫和標點。在許多情況下,完整的句子要比句子碎片更易閱讀。比較短的註釋,如在行尾的註釋,有時可能不夠正式,但你應該和你的風格保持一致。

Although it canbe frustrating to have a code reviewer point out that you are using a commawhen you should be using a semicolon, it is very important that source codemaintain a high level of clarity and readability. Proper punctuation, spelling,and grammar help with that goal.

雖然被別人指出該用分號時卻用了逗號多少有些尷尬,但清晰易讀的程式碼還是很重要的。合適的標點、拼寫和語法能幫助你實現這一目標。

Use TODOcomments for code that is temporary, a short-term solution, or good-enough butnot perfect.

將TODO註釋用在臨時性的、短期解決方案、或足夠好但還不完美的程式碼上。

TODOs shouldinclude the string TODO in all caps, followed by the name, e-mail address, orother identifier of the person who can best provide context about the problemreferenced by the TODO. A colon is optional. The main purpose is to have aconsistent TODO format that can be searched to find the person who can providemore details upon request. A TODO is not a commitment that the personreferenced will fix the problem. Thus when you create a TODO, it is almostalways your name that is given.

TODO註釋應該包括全大寫的“TODO”,接著是能提供最多資訊的人的名字,郵箱地址,或其它個人資訊。冒號是可選的。主要目的是能讓添加註釋的人(或可提供最多資訊的人)按統一的TODO格式搜尋到。TODO註釋不表示相關的人承諾會修復此問題。因此當你新建了一個TODO註釋,它給出的總是你的名字。

// TODO([email protected]): Use a "*" herefor concatenation operator.

// TODO(Zeke) change this to use relations.

If your TODO isof the form "At a future date do something" make sure that you eitherinclude a very specific date ("Fix by November 2005") or a veryspecific event ("Remove this code when all clients can handle XMLresponses.").

如果你的TODO註釋是“未來某時會做某事[f5] ”的格式,要確保你要麼包括了一個具體的時間(“2005年11月修復”)要麼包括具體的事件(“當所有客戶端都能處理XML反饋後移除此程式碼”)。

Mark deprecatedinterface points with DEPRECATED comments.

用DEPRECATED註釋來標記過期的介面。

You can mark aninterface as deprecated by writing a comment containing the word DEPRECATED inall caps. The comment goes either before the declaration of the interface or onthe same line as the declaration.

你可以通過給某介面加上DEPRECATED的註釋來標記其為過期的。可以在介面宣告之前註釋,也可在同一行註釋。

After the wordDEPRECATED, write your name, e-mail address, or other identifier inparentheses.

在DEPRECATED單詞後的括號裡寫上你的名字、郵箱或其它個人資訊。

A deprecationcomment must include simple, clear directions for people to fix theircallsites. In C++, you can implement a deprecated function as an inlinefunction that calls the new interface point.

過期內容的註釋必須包括簡單清晰的用於指導使用者修正呼叫的提示。在C++中,你可以將一個過期的函式實現為行內函數,在其中呼叫新的介面點。

Marking aninterface point DEPRECATED will not magically cause any callsites to change. Ifyou want people to actually stop using the deprecated facility, you will haveto fix the callsites yourself or recruit a crew to help you.

用DEPRECATED標記一個介面不會魔術般的導致任何呼叫被改變。如果你想要使用者真的停止使用過期的設施,你需要自己修復呼叫或招幾個人來幫你。

New code shouldnot contain calls to deprecated interface points. Use the new interface pointinstead. If you cannot understand the directions, find the person who createdthe deprecation and ask them for help using the new interface point.

新程式碼中不應包含對過期介面點的呼叫。改為使用新介面點。如果你看不懂提示,就找添加了這個過期說明的人,然後請求他幫你使用新介面點。

3 Formatting 格式

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

程式碼風格與格式確實很隨意,但如果所有人都使用同樣的風格,專案就能更容易進行。個體可能不同意格式規則中的每一方面,一些規則也可能需要一些時間來適應,但所有的專案成員都遵守相同的風格規則是很重要的,這樣他們就可以很容易的看懂每個人的程式碼了。

To help youformat code correctly, we've created a settings file for emacs.

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

你每行程式碼的文字最多隻允許80個字元寬。

We recognizethat this rule is controversial, but so much existing code already adheres toit, and we feel that consistency is important.

我們承認這條規則有爭議,但有這麼多現存的程式碼已經遵守它了,我們感覺一致性更重要。

Pros:

Those who favorthis rule argue that it is rude to force them to resize their windows and thereis no need for anything longer. Some folks are used to having several codewindows side-by-side, and thus don't have room to widen their windows in anycase. People set up their work environment assuming a particular maximum windowwidth, and 80 columns has been the traditional standard. Why change it?

優點:

喜歡這條規則的人主張強迫他們改變編輯器視窗大小很野蠻,而且更長的程式碼也沒什麼必要。一些人習慣多個程式碼視窗挨著排,因此沒辦法讓他們的視窗再寬一點點了。人們都將他們的工作環境設為某個特定的視窗寬度,而80列就是傳統的標準。為什麼要改變它?

Cons:

Proponents ofchange argue that a wider line can make code more readable. The 80-column limitis an hidebound throwback to 1960s mainframes; modern equipment has widescreens that can easily show longer lines.

缺點:

支援改變此規則的人認為更寬的行能令程式碼更有可讀性。80列的限制可以回溯到古老的1960年代的主機;現代機器有著更寬的螢幕,能輕易的顯示更寬的行。

Decision:

結論:

80 characters isthe maximum.

80個字元,不能再多了。

Exception: if acomment line contains an example command or a literal URL longer than 80characters, that line may be longer than 80 characters for ease of cut andpaste.

例外:如果註釋行包括了一個示例命令或URL的文字超過了80個字元,這行就可以超過80個字元,以便複製剪下。

Exception: an#include statement with a long path may exceed 80 columns. Try to avoidsituations where this becomes necessary.

例外:#include語句如果路徑很長的話可能超過80列。試著避免出現這種情況。

Exception: youneedn't be concerned about header guards that exceed the maximum length.

例外:你不必關心標頭檔案的守衛是否超過了最大長度。

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

要少用非ASCII字元,即使用的話也必須用UTF-8格式。

You shouldn'thard-code user-facing text in source, even English, so use of non-ASCIIcharacters should be rare. However, in certain cases it is appropriate toinclude such words in your code. For example, if your code parses data filesfrom foreign sources, it may be appropriate to hard-code the non-ASCIIstring(s) used in those data files as delimiters. More commonly, unittest code(which does not need to be localized) might contain non-ASCII strings. In suchcases, you should use UTF-8, since that is an encoding understood by most toolsable to handle more than just ASCII. Hex encoding is also OK, and encouragedwhere it enhances readability — for example, "\xEF\xBB\xBF" is theUnicode zero-width no-break space character, which would be invisible ifincluded in the source as straight UTF-8.

你不應將使用者介面文字硬編碼進原始檔中,即使是英文,這樣就不怎麼需要用非ASCII字元了。但是,有些場合就適合將非ASCII單詞放進程式碼中。例如,如果你的程式碼要解析國外來源的資料檔案,將在這些檔案中充當定界符的非ASCII字串硬編碼可能會比較合適。更常見的情況是單元測試程式碼(不需要本地化)可能會包含非ASCII字元。這些場合你都應該用UTF-8格式,因為這種編碼被大多數能處理不止ASCII這一種編碼的工具所支援。16進位制編碼也可以,在能增強可讀性的地方推薦這種編碼——例如,“\xEF\xBB\xBF”是Unicode零寬度無間斷空格字元,而如果直接按UTF-8格式加進原始檔中就看不到這個字元[f6] 了。

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

We use spacesfor indentation. Do not use tabs in your code. You should set your editor toemit spaces when you hit the tab key.

我們用空格進行縮排。不要在你的程式碼中用tab。你應該將你的編輯器設定為點選tab鍵時輸出空格。

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

返回值型別要與函式名同行,引數名如果合適的話也在同行。

Functions looklike this:

像這樣的函式:

ReturnType ClassName::FunctionName(Typepar_name1, Type par_name2) {

 DoSomething();

  ...

}

If you have toomuch text to fit on one line:

如果你有太多東西寫在了同一行:

ReturnTypeClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,

                                            Type par_name3) {

 DoSomething();

  ...

}

or if you cannotfit even the first parameter:

或如果你連第一個引數都放不進同一行:

ReturnTypeLongClassName::ReallyReallyReallyLongFunctionName(

   Type par_name1,  // 4 space indent

   Type par_name2,

   Type par_name3) {

 DoSomething();  // 2 space indent

  ...

}

Some points tonote:

1.    The return type is always onthe same line as the function name.

2.    The open parenthesis is alwayson the same line as the function name.

3.    There is never a space betweenthe function name and the open parenthesis.

4.    There is never a space betweenthe parentheses and the parameters.

5.    The open curly brace is alwaysat the end of the same line as the last parameter.

6.    The close curly brace is eitheron the last line by itself or (if other style rules permit) on the same line asthe open curly brace.

7.    There should be a space betweenthe close parenthesis and the open curly brace.

8.    All parameters should be named,with identical names in the declaration and implementation.

9.    All parameters should bealigned if possible.

10.  Default indentation is 2 spaces.

11.  Wrapped parameters have a 4 space indent.

一些要記住的要點:

1.    返回值型別總是與函式名在同一行。

2.    開括號[f8] 總要與函式名在同一行。

3.    在函式名與開括號間不要有空格。

4.    在括號和引數間不要有空格。

5.    開的大括號[f9] 總與最後一個引數同行。

6.    閉的大括號可以自己在最後一行或(如果其它規則允許)與開的大括號在同一行。

7.    在閉括號與開大括號間應該有個空格。

8.    所有的引數都要有名字,宣告和實現中的名字要相同。

9.    如果可能,所有引數都應該對齊。

10.  預設縮排是2個空格。

11.  換行後的引數有4個空格的縮排。

If someparameters are unused, comment out the variable name in the functiondefinition:

如果一些引數沒被用到,在函式定義處將引數名註釋起來。

// Always have named parameters ininterfaces.

class Shape {

 public:

 virtual void Rotate(double radians) = 0;

}

// Always have named parameters in thedeclaration.

class Circle : public Shape {

 public:

 virtual void Rotate(double radians);

}

// Comment out unused named parameters indefinitions.

void Circle::Rotate(double /*radians*/) {}

// Bad - if someone wants to implementlater, it's not clear what the

// variable means.

void Circle::Rotate(double) {}

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

儘量放在同一行,否則,將實參封裝在圓括號中。

Function callshave the following format:

函式呼叫遵循下面的格式:

bool retval = DoSomething(argument1,argument2, argument3);

If the argumentsdo not all fit on one line, they should be broken up onto multiple lines, witheach subsequent line aligned with the first argument. Do not add spaces afterthe open paren or before the close paren:

如果實參放不進一行,就將它們分成多行,分出的每行都要和第一個引數對齊。不要在開括號後和閉括號前加空格:

bool retval =DoSomething(averyveryveryverylongargument1,

                          argument2,argument3);

If the functionhas many arguments, consider having one per line if this makes the code morereadable:

如果函式有很多引數,考慮每行寫一個引數,可以增強可讀性:

bool retval = DoSomething(argument1,

                          argument2,

                          argument3,

                          argument4);

If the functionsignature is so long that it cannot fit within the maximum line length, you mayplace all arguments on subsequent lines:

如果函式原型太長,以至於超過了行的最大長度,你可以將所有引數獨立成行:

if (...) {

  ...

  ...

  if(...) {

   DoSomethingThatRequiresALongFunctionName(

       very_long_argument1,  // 4 spaceindent

       argument2,

       argument3,

       argument4);

  }

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

建議括號內沒有空格。else關鍵字放在新行中。

There are twoacceptable formats for a basic conditional statement. One includes spacesbetween the parentheses and the condition, and one does not.

有兩種基本的條件語句格式都可使用。一種在括號和條件式之間有空格,另一種沒有。

The most commonform is without spaces. Either is fine, but be consistent. If you are modifyinga file, use the format that is already present. If you are writing new code,use the format that the other files in that directory or project use. If indoubt and you have no personal preference, do not add the spaces.

最常見的格式是沒有空格的。用哪種都可以,但要保持一致。如果你修改一個檔案,就用當前的格式。如果你在寫新程式碼,用專案或目錄中其它檔案的格式。如果不知道用哪個,你也沒有個人傾向的話,不要加空格。

if (condition) {  // no spaces inside parentheses

 ...  // 2 space indent.

} else if (...) {  // The else goes on the same line as theclosing brace.

  ...

} else {

  ...

}

If you preferyou may add spaces inside the parentheses:

如果你喜歡的話,也可以在括號與條件式之間加空格:

if ( condition ) {  // spaces inside parentheses - rare

 ...  // 2 space indent.

} else { // The else goes on the same line as the closing brace.

  ...

}

Note that in allcases you must have a space between the if and the open parenthesis. You mustalso have a space between the close parenthesis and the curly brace, if you'reusing one.

注意任何情況下你都要在if和開括號間放一個空格。你也必須在閉括號和大括號間放空格。

if(condition)     // Bad - space missing after IF.

if (condition){   // Bad - space missing before {.

if(condition){    // Doubly bad.

if (condition) {  // Good - proper space after IF and before {.

Shortconditional statements may be written on one line if this enhances readability.You may use this only when the line is brief and the statement does not use theelse clause.

短的條件語句也可以寫在同一行內,如果不影響可讀性的話。只有在行很短且沒有else分句時才能這麼用。

if (x == kFoo) return new Foo();

if (x == kBar) return new Bar();

This is notallowed when the if statement has an else:

如果if語句包含else的話不許如下這麼用:

// Not allowed - IF statement on one linewhen there is an ELSE clause

if (x) DoThis();

else DoThat();

In general,curly braces are not required for single-line statements, but they are allowedif you like them; conditional or loop statements with complex conditions orstatements may be more readable with curly braces. Some projects require thatan if must always always have an accompanying brace.

通常開的大括號不需要單獨一行,但你喜歡的話也可以;有著複雜的條件或狀態的條件語句和迴圈語句後面跟大括號的話,可能會更有可讀性。一些專案要求if後面必須跟著大括號。

if (condition)

 DoSomething();  // 2 space indent.

if (condition) {

 DoSomething();  // 2 space indent.

}

However, if onepart of an if-else statement uses curly braces, the other part must too:

但是,如果if-else語句中的一部分用大括號了,另一部分也必須用:

// Not allowed - curly on IF but not ELSE

if (condition) {

  foo;

} else

  bar;

// Not allowed - curly on ELSE but not IF

if (condition)

  foo;

else {

  bar;

}

// Curly braces around both IF and ELSErequired because

// one of the clauses used braces.

if (condition) {

  foo;

} else {

  bar;

}

Switchstatements may use braces for blocks. Empty loop bodies should use {} orcontinue.

switch語句可以用大括號來分段。空迴圈體應該用{}或continue。

case blocks inswitch statements can have curly braces or not, depending on your preference.If you do include curly braces they should be placed as shown below.

switch的case塊可以用大括號包起來,也可以不用,取決於你的喜好。如果你引入大括號了,應該參照下面的用法。

If notconditional on an enumerated value, switch statements should always have adefault case (in the case of an enumerated value, the compiler will warn you ifany values are not handled). If the default case should never execute, simplyassert:

如果有不滿足case條件的列舉值,switch語句應該總是包含一個預設case塊(如果有輸入值沒有case條件去處理,編譯器會警告)。如果預設case永遠都不該執行,就放一個assert。

switch (var) {

  case0: {  // 2 space indent

   ...      // 4 space indent

   break;

  }

  case1: {

   ...

   break;

  }

 default: {

   assert(false);

  }

}

Empty loopbodies should use {} or continue, but not a single semicolon.

空的迴圈體應該用{}或continue,而不是單獨的一個分號。

while (condition) {

  //Repeat test until it returns false.

}

for (int i = 0; i < kSomeNumber; ++i){}  // Good - empty body.

while (condition) continue;  // Good - continue indicates no logic.

while (condition);  // Bad - looks like part of do/while loop.

No spaces aroundperiod or arrow. Pointer operators do not have trailing spaces.

在句點和箭頭前後沒有空格。指標操作符後面沒有尾隨的空格。

The followingare examples of correctly-formatted pointer and reference expressions:

下面是格式正確的指標和引用表示式:

x = *p;

p = &x;

x = r.y;

x = r->y;

Note that:

1.    There are no spaces around theperiod or arrow when accessing a member.

2.    Pointer operators have no spaceafter the * or &.

注意:

1.    在訪問成員時,句點和箭頭的前後沒有空格。

2.    指標操作符中*和&後面沒有空格。

When declaring apointer variable or argument, you may place the asterisk adjacent to either thetype or to the variable name:

當宣告指標變數或引數時,星號可以挨著型別也可以挨著變數名:

// These are fine, space preceding.

char *c;

const string &str;

// These are fine, space following.

char* c;   // but remember to do "char* c, *d, *e, ...;"!

const string& str;

char * c; // Bad - spaces on both sides of *

const string & str;  // Bad - spaces on both sides of &

You should dothis consistently within a single file, so, when modifying an existing file,use the style in that file.

你應該在同一個檔案中保持一致,所以在修改一個已有的檔案時,用檔案原有的風格。

When you have aboolean expression that is longer than the standard line length, be consistentin how you break up the lines.

如果一個布林表示式比標準行寬還要長,你要像其它情況一樣將它分成多行。

In this example,the logical AND operator is always at the end of the lines:

if (this_one_thing > this_other_thing&&

   a_third_thing == a_fourth_thing &&

   yet_another && last_one) {

  ...

}

Note that whenthe code wraps in this example, both of the && logical AND operatorsare at the end of the line. This is more common in Google code, though wrappingall operators at the beginning of the line is also allowed. Feel free to insertextra parentheses judiciously because they can be very helpful in increasingreadability when used appropriately. Also note that you should always use thepunctuation operators, such as && and ~, rather than the word operators,such as and and compl.

注意到本例中程式碼被分成多行,其中的&&操作符都在行尾。儘管也可以將所有操作符都對齊到行首,本例中的用法在谷歌的程式碼中更常見。這樣可以方便插入括號,適當使用對提升可讀性很有幫助。同樣注意,你應該總是用符號表示的操作符,如&&和~,而不是用單詞表示[f11] ,如and和compl。

Do notneedlessly surround the return expression with parentheses.

不要用不必要的括號括起返回表示式。

Use parenthesesin return expr; only where you would use them in x = expr;.

返回表示式expr只有在令它為賦值式時會引起歧義的地方才能用括號括起:

return result;                  // No parentheses in thesimple case.簡單場合不用括號

return (some_long_condition &&  // Parentheses ok to make a complex複雜表示式用括號可讀性更好

       another_condition);     //     expression more readable.

return (value);                // You wouldn't write var =(value);你不會寫var=(value)這樣的式子的[f12] 

return(result);                // return is not a function!return不是個函式!

Your choice of =or ().

可以用=也可以用()。

You may choosebetween = and (); the following are all correct:

你可以在=和()中選一種形式[f13] ;下面的例子都是正確的:

int x = 3;

int x(3);

string name("Some Name");

string name = "Some Name";

The hash markthat starts a preprocessor directive should always be at the beginning of theline.

預處理指令應該總在行首,不要縮排。

Even whenpreprocessor directives are within the body of indented code, the directivesshould start at the beginning of the line.

即使預處理指令位於縮排的程式碼塊中,它們也不縮排而是總在行首。

// Good - directives at beginning of line

  if(lopsided_score) {

#if DISASTER_PENDING      // Correct -- Starts at beginning of line

   DropEverything();

# if NOTIFY               // OK but not required -- Spacesafter #可以但不需要#後面有空格

   NotifyClient();

# endif

#endif

   BackToNormal();

  }

// Bad - indented directives

  if(lopsided_score) {

   #if DISASTER_PENDING  //Wrong!  The "#if" should be atbeginning of line

   DropEverything();

   #endif                //Wrong!  Do not indent "#endif"

   BackToNormal();

  }

Sections inpublic, protected and private order, each indented one space.

類中各部分按public、protected和private的順序,每個關鍵字縮排1個空格。

The basic formatfor a class declaration (lacking the comments, see Class Comments for adiscussion of what comments are needed) is:

類宣告的基本格式(省略了註釋)是:

class MyClass : public OtherClass {

 public:     // Note the 1 space indent!

 MyClass();  // Regular 2 spaceindent.

 explicit MyClass(int var);

 ~MyClass() {}

  voidSomeFunction();

  voidSomeFunctionThatDoesNothing() {

  }

  voidset_some_var(int var) { some_var_ = var; }

  intsome_var() const { return some_var_; }

 private:

  boolSomeInternalFunction();

  intsome_var_;

  intsome_other_var_;

 DISALLOW_COPY_AND_ASSIGN(MyClass);

};

Things to note:

1.    Any base class name should beon the same line as the subclass name, subject to the 80-column limit.

2.    The public:, protected:, andprivate: keywords should be indented one space.

3.    Except for the first instance,these keywords should be preceded by a blank line. This rule is optional insmall classes.

4.    Do not leave a blank line afterthese keywords.

5.    The public section should befirst, followed by the protected and finally the private section.

6.    See Declaration Order for ruleson ordering declarations within each of these sections.

注意事項:

1.    任何基類的名字都應與子類名字在同一行,遵循80列寬的限制。

2.    public、protected、private關鍵字應該縮排1個空格。

3.    除了第一個出現的關鍵字,其後的關鍵字前面應該有個空行。此規則對於較小的類是可選的。

4.    不要在這些關鍵字後留空行。

5.    public段應在最前,其後是protected段,最後是private段。

Constructorinitializer lists can be all on one line or with subsequent lines indented fourspaces.

建構函式初始化列表可以都放在一行中也可以分成多行,每行縮排4個空格。

There are twoacceptable formats for initializer lists:

初始化列表有兩種可選格式:

// When it all fits on one line:

MyClass::MyClass(int var) : some_var_(var),some_other_var_(var + 1) {}

or

// When it requires multiple lines, indent 4spaces, putting the colon on

// the first initializer line:

MyClass::MyClass(int var)

    :some_var_(var),             // 4 spaceindent

     some_other_var_(var + 1) {  //lined up

  ...

 DoSomething();

  ...

}

The contents ofnamespaces are not indented.

名稱空間的內容不縮排。

Namespaces donot add an extra level of indentation. For example, use:

名稱空間不會增加一層縮排。例如:

namespace {

void foo() { // Correct.  No extra indentationwithin namespace.

  ...

}

}  //namespace

Do not indentwithin a namespace:

名稱空間內不要縮排:

namespace {

  //Wrong.  Indented when it should not be.

  voidfoo() {

   ...

  }

}  //namespace

When declaringnested namespaces, put each namespace on its own line.

宣告巢狀名稱空間時,每個名稱空間單獨一行。

namespace foo {

namespace bar {

Use of horizontalwhitespace depends on location. Never put trailing whitespace at the end of aline.

分情況使用水平留白。永遠不要在行尾放空格。

General 通常情況

void f(bool b) {  // Open braces should always have a spacebefore them.開括號前應該有一個空格

  ...

int i = 0; // Semicolons usually have no space before them.分號前通常沒有空格

int x[] = { 0 };  // Spaces inside braces for arrayinitialization are陣列初始化時括號內的空格可選

int x[] = {0};    // optional.  If you use them, put them on both sides!用的時候要兩邊都加空格

// Spaces arou