From f7facf90268cee3f4f25f08e49147c782b1185a0 Mon Sep 17 00:00:00 2001 From: mmentovai Date: Fri, 23 Oct 2009 21:01:49 +0000 Subject: [PATCH] Update C++ style guide to 3.146: - Make the messaging on DISALLOW_EVIL_CONSTRUCTORS more clear that we should not be rewriting old code but should simply prefer DISALLOW_COPY_AND_ASSIGN on new code. - s/Initializer Lists/Constructor Initializer Lists/ since people search for this based on knowing it's part of the constructor, but forget the precise name. - Allow data members in a test fixture to be private. - Loosen restrictions on globals. - Add explicit guideline for nested namespace formatting. - Strengthen the prohibition against operator overloading for operator&. - Add recommendation for "_" over "-" in file names. - Revise the "Copy Constructors" section for brevity and clarity. Emphasize preference for standard over nonstandard copy operations. - Weaken the wording at the top of the "Doing Work in Constructors" section, making it clear that Init() methods are not absolutely required for non-trivial initialization. - Fix minor typos and grammatical errors. Update Objective-C style guide to 2.14: - Add the Rule of Four for indenting parameters. Allow either of two forms for formatting methods with short first keywords. - Update the guidance on BOOL vs. bool. - Whitespace cleanup. Update Python style guide to 2.14: - Consolidate discussion of the string module, apply, map, filter, and reduce into a single section. - Make it explicit that functions and classes can be nested inside methods. --- cppguide.xml | 167 ++++++++++++++++++++---------------- objcguide.xml | 229 +++++++++++++++++++++++++++++++------------------- pyguide.html | 96 ++++++++------------- 3 files changed, 274 insertions(+), 218 deletions(-) diff --git a/cppguide.xml b/cppguide.xml index 7840cf2..cdd0444 100644 --- a/cppguide.xml +++ b/cppguide.xml @@ -4,7 +4,7 @@

-Revision 3.133 +Revision 3.146

@@ -96,6 +96,7 @@ Tashana Landray reader is familiar with the language.

+ @@ -750,34 +751,42 @@ Tashana Landray

- Objects with static storage duration, including global variables, + Objects with static storage duration, including global variables, static variables, static class member variables, and function static - variables, must be Plain Old Data (POD): only ints, chars, floats, and - void, and arrays of/structs of/pointers to POD. Static variables must - not be initialized with the result of a function; and non-const static - variables must not be used in threaded code. + variables, must be Plain Old Data (POD): only ints, chars, floats, or + pointers, or arrays/structs of POD.

- The order in which class constructors, destructors, and initializers for + The order in which class constructors and initializers for static variables are called is only partially specified in C++ and can even change from build to build, which can cause bugs that are difficult - to find. For example, at program-end time a static variable might have + to find. Therefore in addition to banning globals of class type, we do + not allow static POD variables to be initialized with the result of a + function, unless that function (such as getenv(), or getpid()) does not + itself depend on any other globals. +

+

+ Likewise, the order in which destructors are called is defined to be the + reverse of the order in which the constructors were called. Since + constructor order is indeterminate, so is destructor order. + For example, at program-end time a static variable might have been destroyed, but code still running -- perhaps in another thread -- - tries to access it and fails. + tries to access it and fails. Or the destructor for a static 'string' + variable might be run prior to the destructor for another variable that + contains a reference to that string.

As a result we only allow static variables to contain POD data. This - rule completely disallows vector (use C arrays instead), - string (use const char*), or anything that - contains or points to any class instance in any way, from ever being a - part of a static variable. For similar reasons, we don't allow static - variables to be initialized with the result of a function call. + rule completely disallows vector (use C arrays instead), or + string (use const char []).

If you need a static or global variable of a class type, consider - initializing a pointer which you never free from your main() function - or from pthread_once(). + initializing a pointer (which will never be freed), from either your + main() function or from pthread_once(). Note that this must be a raw + pointer, not a "smart" pointer, since the smart pointer's destructor + will have the order-of-destructor issue that we are trying to avoid.

@@ -792,9 +801,9 @@ Tashana Landray - Do only trivial initialization in a constructor. If at all - possible, use an Init() method for non-trivial - initialization. + In general, constructors should merely set member variables to their + initial values. Any complex initialization should go in an explicit + Init() method. @@ -835,9 +844,9 @@ Tashana Landray If your object requires non-trivial initialization, consider - having an explicit Init() method and/or adding a - member flag that indicates whether the object was successfully - initialized. + having an explicit Init() method. In particular, + constructors should not call virtual functions, attempt to raise + errors, access potentially uninitialized global variables, etc. @@ -863,7 +872,7 @@ Tashana Landray

- If your class defines member variables has no other + If your class defines member variables and has no other constructors you must define a default constructor (one that takes no arguments). It should preferably initialize the object in such a way that its internal state is consistent @@ -933,19 +942,22 @@ Tashana Landray

- Use copy constructors only when your code needs to copy a class; - most do not need to be copied and so should use - DISALLOW_COPY_AND_ASSIGN. + Provide a copy constructor and assignment operator only when necessary. + Otherwise, disable them with DISALLOW_COPY_AND_ASSIGN. - The copy constructor is used when copying one object into a - new one (especially when passing objects by value). + The copy constructor and assignment operator are used to create copies + of objects. The copy constructor is implicitly invoked by the + compiler in some situations, e.g. passing objects by value. Copy constructors make it easy to copy objects. STL containers require that all contents be copyable and - assignable. + assignable. Copy constructors can be more efficient than + CopyFrom()-style workarounds because they combine + construction with copying, the compiler can elide them in some + contexts, and they make it easier to avoid heap allocation. Implicit copying of objects in C++ is a rich source of bugs @@ -956,19 +968,35 @@ Tashana Landray

- Most classes do not need to be copyable, and should not have a - copy constructor or an assignment operator. Unfortunately, the - compiler generates these for you, and makes them public, if - you do not declare them yourself. + Few classes need to be copyable. Most should have neither a + copy constructor nor an assignment operator. In many situations, + a pointer or reference will work just as well as a copied value, + with better performance. For example, you can pass function + parameters by reference or pointer instead of by value, and you can + store pointers rather than objects in an STL container.

-

- Consider adding dummy declarations for the copy constructor and - assignment operator in the class' private: section, - without providing definitions. With these dummy routines marked - private, a compilation error will be raised if other code - attempts to use them. For convenience, a - DISALLOW_COPY_AND_ASSIGN macro can be used: + If your class needs to be copyable, prefer providing a copy method, + such as CopyFrom() or Clone(), rather than + a copy constructor, because such methods cannot be invoked + implicitly. If a copy method is insufficient in your situation + (e.g. for performance reasons, or because your class needs to be + stored by value in an STL container), provide both a copy + constructor and assignment operator. +

+

+ If your class does not need a copy constructor or assignment + operator, you must explicitly disable them. + + + To do so, add dummy declarations for the copy constructor and + assignment operator in the private: section of your + class, but do not provide any corresponding definition (so that + any attempt to use them results in a link error). +

+

+ For convenience, a DISALLOW_COPY_AND_ASSIGN macro + can be used:

// A macro to disallow the copy constructor and operator= functions @@ -991,23 +1019,6 @@ Tashana Landray };

- In almost all cases your class should use the - DISALLOW_COPY_AND_ASSIGN - macro as described above. If your class is one of the rare - classes that does need to be copyable, you should document why - this is so in the header file for that class, and you should - define the copy constructor and assignment operator - appropriately. Remember to check for self-assignment in - operator=. -

-

- You may be tempted to make your class copyable so that you - can use it as a value in STL containers. In almost all such - cases you should really put pointers to your - objects in the STL container. You may also want to consider - using - - std::tr1::shared_ptr.

@@ -1107,7 +1118,7 @@ Tashana Landray

Limit the use of protected to those member functions that might need to be accessed from subclasses. - Note that data members must always + Note that data members should be private.

@@ -1256,16 +1267,18 @@ Tashana Landray Overloading also has surprising ramifications. For instance, - you can't forward declare classes that overload - operator&. + if a class overloads unary operator&, it + cannot safely be forward-declared.

In general, do not overload operators. The assignment operator (operator=), in particular, is insidious and should be avoided. You can define functions like - Equals() and CopyFrom() if you need - them. + Equals() and CopyFrom() if you + need them. Likewise, avoid the dangerous + unary operator& at all costs, if there's + any possibility the class might be forward-declared.

However, there may be rare cases where you need to overload @@ -1296,10 +1309,15 @@ Tashana Landray

Make all data members private, and provide - access to them through accessor functions as needed. Typically - a variable would be called foo_ and the accessor - function foo(). You may also want a mutator - function set_foo(). + access to them through accessor functions as needed (for + technical reasons, we allow data members of a test fixture class + to be protected 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().

@@ -2603,7 +2621,7 @@ Tashana Landray convention that your project - uses. + uses. If there is no consistent local pattern to follow, prefer "_".

@@ -2978,8 +2996,8 @@ Tashana Landray

- Every file should have a comment at the top, below the - and author line, that describes the contents of the file. + Every file should have a comment at the top, below the copyright + notice and author line, that describes the contents of the file.

Generally a .h file will describe the classes @@ -4003,7 +4021,7 @@ Tashana Landray - +

Constructor initializer lists can be all on one line or with subsequent lines indented four spaces. @@ -4064,6 +4082,13 @@ Tashana Landray } // namespace +

+ When declaring nested namespaces, put each namespace on its own line. +

+ + namespace foo { + namespace bar { + @@ -4352,7 +4377,7 @@ Tashana Landray

-Revision 3.133 +Revision 3.146

diff --git a/objcguide.xml b/objcguide.xml index 24e442f..0ffb3dd 100644 --- a/objcguide.xml +++ b/objcguide.xml @@ -4,7 +4,7 @@

-Revision 2.12 +Revision 2.14

@@ -16,7 +16,7 @@ Revision 2.12 Dave MacLachlan - + @@ -94,7 +94,7 @@ Revision 2.12

Google has already released open-source code that conforms to these - guidelines as part of the + guidelines as part of the Google Toolbox for Mac project @@ -102,13 +102,13 @@ Revision 2.12 Code meant to be shared across different projects is a good candidate to be included in this repository.

- +

Note that this guide is not an Objective-C tutorial. We assume that the reader is familiar with the language. If you are new to Objective-C or - need a refresher, please read + need a refresher, please read The Objective-C Programming Language . @@ -117,7 +117,7 @@ Revision 2.12 - +

They say an example is worth a thousand words so let's start off with an example that should give you a feel for the style, spacing, naming, etc. @@ -135,9 +135,9 @@ Revision 2.12 // Created by Greg Miller on 6/13/08. // Copyright 2008 Google, Inc. All rights reserved. // - + #import <Foundation/Foundation.h> - + // A sample class demonstrating good Objective-C style. All interfaces, // categories, and protocols (read: all top-level declarations in a header) // MUST be commented. Comments must also be adjacent to the object they're @@ -149,32 +149,32 @@ Revision 2.12 NSString *foo_; NSString *bar_; } - + // Returns an autoreleased instance of GMFoo. See -initWithString: for details // about the argument. + (id)fooWithString:(NSString *)string; - + // Designated initializer. |string| will be copied and assigned to |foo_|. - (id)initWithString:(NSString *)string; - + // Gets and sets the string for |foo_|. - (NSString *)foo; - (void)setFoo:(NSString *)newFoo; - + // Does some work on |blah| and returns YES if the work was completed // successfuly, and NO otherwise. - (BOOL)doWorkWithString:(NSString *)blah; - + @end - +

An example source file, demonstating the correct commenting and spacing for the @implementation of an interface. It also includes the reference implementations for important methods like getters and setters, init, and dealloc.

- + // // GTMFoo.m @@ -183,49 +183,49 @@ Revision 2.12 // Created by Greg Miller on 6/13/08. // Copyright 2008 Google, Inc. All rights reserved. // - + #import "GTMFoo.h" - - + + @implementation GTMFoo - + + (id)fooWithString:(NSString *)string { return [[[self alloc] initWithString:string] autorelease]; } - + // Must always override super's designated initializer. - (id)init { return [self initWithString:nil]; } - + - (id)initWithString:(NSString *)string { if ((self = [super init])) { foo_ = [string copy]; bar_ = [[NSString alloc] initWithFormat:@"hi %d", 3]; } - return self; + return self; } - + - (void)dealloc { [foo_ release]; [bar_ release]; [super dealloc]; } - + - (NSString *)foo { return foo_; } - + - (void)setFoo:(NSString *)newFoo { [foo_ autorelease]; - foo_ = [newFoo copy]; + foo_ = [newFoo copy]; } - + - (BOOL)doWorkWithString:(NSString *)blah { // ... return NO; } - + @end @@ -291,7 +291,7 @@ Revision 2.12

If you have too many parameters to fit on one line, giving each its - own line is preferred. If multiple lines are used, align each using + own line is preferred. If multiple lines are used, align each using the : before the parameter.

@@ -301,9 +301,33 @@ Revision 2.12 ... } +

+ When the first keyword is shorter than the others, indent the later + lines by at least four spaces. You can do this by making keywords + line up vertically, not aligning colons: +

+ + - (void)short:(GTMFoo *)theFoo + longKeyword:(NSRect)theRect + evenLongerKeyword:(float)theInterval { + ... + } + +

+ Or you may align all colons, indenting the first keyword if needed, + as below. In editing existing source, use the convention in that + file. +

+ + - (void) short:(GTMFoo *)theFoo + longKeyword:(NSRect)theRect + evenLongerKeyword:(float)theInterval { + ... + } + - + The @public and @private access modifiers @@ -322,7 +346,7 @@ Revision 2.12 ... } @end - + @@ -352,11 +376,11 @@ Revision 2.12 - + - +

Naming rules are very important in maintainable code. Objective-C method names tend to be very long, but this has the benefit that a block of code @@ -368,6 +392,12 @@ Revision 2.12 in variable names, whereas this guide recommends the use of intercaps, which is standard in the Objective-C community.

+

+ Any class, category, method, or variable name may use all capitals for + initialisms + within the name. This follows Apple's standard of using all capitals + within a name for initialisms such as URL, TIFF, and EXIF. +

When writing Objective-C++, however, things are not so cut and dry. Many projects need to implement cross-platform C++ APIs with some Objective-C @@ -440,7 +470,7 @@ Revision 2.12

// file: cross_platform_header.h - + class CrossPlatformAPI { public: ... @@ -448,10 +478,10 @@ Revision 2.12 private: int an_instance_var_; }; - + // file: mac_implementation.mm #include "cross_platform_header.h" - + // A typical Objective-C class, using Objective-C naming. @interface MyDelegate : NSObject { @private @@ -468,7 +498,7 @@ Revision 2.12 NSLog(@"%@", tempString); } @end - + // The platform-specific implementation of the C++ class, using // C++ naming. int CrossPlatformAPI::DoSomethingPlatformSpecific() { @@ -479,7 +509,7 @@ Revision 2.12 - + Class names (along with category and protocol names) should start as @@ -502,7 +532,7 @@ Revision 2.12 Category names should start with a 2 or 3 character prefix identifying the category as part of a project or open for general use. The category name should incorporate the name of the class it's - extending. + extending.

@@ -520,7 +550,7 @@ Revision 2.12

- + Method names should start as lowercase and then use mixed case. @@ -571,36 +601,36 @@ Revision 2.12 code immediately understandable by a new reader. For example:

- int w; - int nerr; - int nCompConns; + int w; + int nerr; + int nCompConns; tix = [[NSMutableArray alloc] init]; obj = [someObject object]; p = [network port]; - int numErrors; - int numCompletedConnections; + int numErrors; + int numCompletedConnections; tickets = [[NSMutableArray alloc] init]; userInfo = [someObject object]; port = [network port]; - +

Instance variables are mixed case and should be suffixed with a trailing underscore, e.g. usernameTextField_. However, we permit an exception when binding to a member variable using - KVO/KVC and Objective-C 2.0 cannot be used (due to OS release + KVO/KVC and Objective-C 2.0 cannot be used (due to OS release constraints). In this case, it is acceptable to prefix the variable - with an underscore, per Apple's accepted practices for key/value + with an underscore, per Apple's accepted practices for key/value naming. If Objective-C 2.0 can be used, @property and @synthesize provide a solution that conforms to the naming guidelines.

- +

Constant names (#defines, enums, const local variables, etc.) should @@ -729,7 +759,7 @@ Revision 2.12

Make the pointer ownership model as explicit as possible when it falls - outside the most common Objective-C usage idioms. + outside the most common Objective-C usage idioms.

@@ -772,7 +802,7 @@ Revision 2.12

- + @@ -794,7 +824,7 @@ Revision 2.12 - + Comment and clearly identify your designated initializer. @@ -867,7 +897,7 @@ Revision 2.12 @implementation GTMFoo(PrivateDelegateHandling) ... - (NSString *)doSomethingWithDelegate { - // Implement this method + // Implement this method } ... @end @@ -883,7 +913,7 @@ Revision 2.12

If you are using Objective-C 2.0, you should instead declare your private category using a class - extension, for example: + extension, for example:

@interface GMFoo () { ... } @@ -986,7 +1016,7 @@ Revision 2.12 - + When creating new temporary objects, autorelease them on @@ -1029,7 +1059,7 @@ Revision 2.12 - (void)setFoo:(GMFoo *)aFoo { [foo_ autorelease]; // Won't dealloc if |foo_| == |aFoo| - foo_ = [aFoo retain]; + foo_ = [aFoo retain]; } @@ -1091,7 +1121,7 @@ Revision 2.12 void foo() { exceptiontest a; NSException *exception = [NSException exceptionWithName:@"foo" - reason:@"bar" + reason:@"bar" userInfo:nil]; @throw exception; } @@ -1155,30 +1185,58 @@ Revision 2.12 - Be careful with BOOL return values and mixing - bool with BOOL. Avoid comparing directly - with YES. + Be careful when converting general integral values to BOOL. + Avoid comparing directly with YES.

- Only use the constants YES and NO for BOOL return values - and assignments. Common mistakes include casting an array's size or - a pointer value as a BOOL, which depending on the value of the last - byte, could still result in a NO value. + BOOL is defined as an unsigned char in Objective-C which + means that it can have values other than YES (1) and + NO (0). Do not cast or convert general integral values + directly to BOOL. Common mistakes include casting or + converting an array's size, a pointer value, or the result of a bitwise + logic operation to a BOOL which, depending on the value of + the last byte of the integral result, could still result in a + NO value. When converting a general integral value to a + BOOL use ternery operators to return a YES + or NO value.

- Also be careful when interoperating with C++ and its bool - type. Don't just assume that YES and NO - map directly to true and false. You can use - the ternary operator to succinctly map between them. + You can safely interchange and convert BOOL, + _Bool and bool (see C++ Std 4.7.4, 4.12 and + C99 Std 6.3.1.2). You cannot safely interchange BOOL and + Boolean so treat Booleans as a general + integral value as discussed above. Only use BOOL in + Objective C method signatures.

+

+ Using logical operators (&&, || and + !) with BOOL is also valid and will return + values that can be safely converted to BOOL without the + need for a ternery operator. +

+ + - (BOOL)isBold { + return [self fontTraits] & NSFontBoldTrait; + } + - (BOOL)isValid { + return [self stringValue]; + } + - bool b = myBOOL ? true : false; // to go one way... - myBOOL = b ? YES : NO; // ... or the other + - (BOOL)isBold { + return ([self fontTraits] & NSFontBoldTrait) ? YES : NO; + } + - (BOOL)isValid { + return [self stringValue] != nil; + } + - (BOOL)isEnabled { + return [self isValid] && [self isBold]; + }

- Finally, don't directly compare BOOL variables directly - with YES. Not only is is harder to read for those + Also, don't directly compare BOOL variables directly + with YES. Not only is it harder to read for those well-versed in C, the first point above demonstrates that return values may not always be what you expect.

@@ -1192,9 +1250,10 @@ Revision 2.12 if (great) // ...be great! +
- + Properties in general are allowed with the following caveat: properties @@ -1202,7 +1261,7 @@ Revision 2.12 on the iPhone and MacOS X 10.5 (Leopard) and higher. Dot notation to access properties is not allowed. - +

A property's associated instance variable's name must conform to the @@ -1212,7 +1271,7 @@ Revision 2.12

Use the @synthesize directive to rename the property correctly.

- + @interface MyClass : NSObject { @private @@ -1220,7 +1279,7 @@ Revision 2.12 } @property(copy, nonatomic) NSString *name; @end - + @implementation MyClass @synthesize name = name_; @end @@ -1231,7 +1290,7 @@ Revision 2.12 A property's declaration must come immediately after the instance variable block of a class interface. A property's definition must come immediately after the @implementation block in a - class definition. They are indented at the same level as the + class definition. They are indented at the same level as the @interface or @implementation statements that they are enclosed in.

@@ -1242,7 +1301,7 @@ Revision 2.12 } @property(copy, nonatomic) NSString *name; @end - + @implementation MyClass @synthesize name = name_; - (id)init { @@ -1265,7 +1324,7 @@ Revision 2.12

CFTypes should always have the @dynamic implementation - directive. + directive.

Since CFTypes can't have the retain property @@ -1290,7 +1349,7 @@ Revision 2.12 @interface MyClass : NSObject @property(readonly) NSString *name; @end - + @implementation MyClass . . @@ -1304,7 +1363,7 @@ Revision 2.12 @interface MyClass : NSObject @property(readonly) NSString *name; @end - + @implementation MyClass @dynamic name; . @@ -1333,12 +1392,12 @@ Revision 2.12

  • Dot notation is purely syntactic sugar for standard method calls, whose readability gains are debatable. It just gives you another - way to make method calls. + way to make method calls.
  • It obscures the type that you are dereferencing. When one sees: [foo setBar:1] it is immediately clear that you are - working with an Objective-C object. When one sees + working with an Objective-C object. When one sees foo.bar = 1 it is not clear if foo is an object, or a struct/union/C++ class.
  • @@ -1366,7 +1425,7 @@ Revision 2.12 - + Delegate objects should not be retained. @@ -1430,7 +1489,7 @@ Revision 2.12

    -Revision 2.12 +Revision 2.14

    diff --git a/pyguide.html b/pyguide.html index 08a0d54..2bf4363 100644 --- a/pyguide.html +++ b/pyguide.html @@ -1,5 +1,4 @@ - - + Google Python Style Guide @@ -95,7 +94,7 @@

    Google Python Style Guide

    - Revision 2.12 + Revision 2.14

    @@ -124,7 +123,7 @@ +pychecker Imports Packages Exceptions Global variables Nested/Local/Inner Classes and Functions List Comprehensions Default Iterators and Operators Generators Lambda Functions Default Argument Values Properties True/False evaluations Deprecated Language Features Lexical Scoping Function and Method Decorators Threading Power Features @@ -438,9 +437,9 @@ from sound.effects import echo

    Definition: - A class can be defined inside of a function or class. A function - can be defined inside a function. Nested functions have read-only - access to variables defined in enclosing scopes. + A class can be defined inside of a method, function, or class. A + function can be defined inside a method or function. Nested functions + have read-only access to variables defined in enclosing scopes.

    Pros: @@ -601,39 +600,6 @@ from sound.effects import echo

    -

    Using apply, filter, map, reduce

    - - - Avoid in favor of list comprehensions and for-loops. - -
    -
    No:  map/filter:          map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
    -

    -
    -

    Lambda Functions

    @@ -720,8 +686,8 @@ from sound.effects import echo
    No:  def foo(a, b=[]):
              ...

    - Calling code must use named values for the default args. This - helps document the code somewhat and helps prevent and detect + Calling code must use named values for arguments with a default value. + This helps document the code somewhat and helps prevent and detect interface breakage when more arguments are added.

    @@ -912,32 +878,38 @@ from sound.effects import echo
             

    -

    String Methods

    - +

    Deprecated Language Features

    + - Use string methods instead of the string module where - possible. + Use string methods instead of the string module + where possible. Use function call syntax instead + of apply. Use list comprehensions + and for loops instead of filter, + map, and reduce. -
    -
    Yes: words = foo.split(':')
    +Decision: + We do not use any Python version which does not support + these features, so there is no reason not to use the new + styles. +
    No:  words = string.split(foo, ':')
    +
    +     map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
    +
    +     apply(fn, args, kwargs)
    +
    Yes: words = foo.split(':')
    +
    +     [x[1] for x in my_list if x[2] == 5]
    +
    +     fn(*args, **kwargs)

    @@ -2011,7 +1983,7 @@ Don't do this.

    -Revision 2.12 +Revision 2.14