From 6fb1d3742012a73c05b8e1de44046510751f4ad8 Mon Sep 17 00:00:00 2001
From: mmentovai
+ Hooray! Now you know you can expand points to get more
+ details. Alternatively, there's an "expand all" at the
+ top of this document.
+
+ C++ is the main development language
+
+ used by many of Google's open-source
+ projects.
+ As every C++ programmer knows, the language has many powerful features,
+ but this power brings with it complexity, which in turn can make code
+ more bug-prone and harder to read and maintain.
+
+ The goal of this guide is to manage this complexity by describing
+ in detail the dos and don'ts of writing C++
+ code. These rules exist to
+ keep
+
+ the
+ code base manageable while still allowing coders to use C++ language
+ features productively.
+
+ Style, also known as readability, is what we call the
+ conventions that govern our C++ code. The term Style is a bit of a
+ misnomer, since these conventions cover far more than just source
+ file formatting.
+
+ One way in which we keep the code base manageable is by enforcing
+ consistency.
+
+ It is very important that any
+
+ programmer
+ be able to look at another's code and quickly understand it.
+ Maintaining a uniform style and following conventions means that we can
+ more easily use "pattern-matching" to infer what various symbols are
+ and what invariants are true about them. Creating common, required
+ idioms and patterns makes code much easier to understand. In some
+ cases there might be good arguments for changing certain style
+ rules, but we nonetheless keep things as they are in order to
+ preserve consistency.
+
+ Another issue this guide addresses is that of C++ feature bloat.
+ C++ is a huge language with many advanced features. In some cases
+ we constrain, or even ban, use of certain features. We do this to
+ keep code simple and to avoid the various common errors and
+ problems that these features can cause. This guide lists these
+ features and explains why their use is restricted.
+
+
+ Open-source projects developed by Google
+ conform to the requirements in this guide.
+
+ Note that this guide is not a C++ tutorial: we assume that the
+ reader is familiar with the language.
+
+
+ In general, every
+ 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.
+
+ To guarantee uniqueness, they should be based on the full path
+ in a project's source tree. For example, the file
+
+ When you include a header file you introduce a dependency that
+ will cause your code to be recompiled whenever the header file
+ changes. If your header file includes other header files, any
+ change to those files will cause any code that includes your
+ header to be recompiled. Therefore, we prefer to minimize
+ includes, particularly includes of header files in other
+ header files.
+
+ You can significantly minimize the number of header files you
+ need to include in your own header files by using forward
+ declarations. For example, if your header file uses the
+
+ How can we use a class
+ On the other hand, you must include the header file for
+
+ Sometimes it makes sense to have pointer (or better,
+
+ Of course,
+ A decent rule of thumb is to not inline a function if it is
+ more than 10 lines long. Beware of destructors, which are
+ often longer than they appear because of implicit member-
+ and base-destructor calls!
+
+ Another useful rule of thumb: it's typically not cost
+ effective to inline functions with loops or switch
+ statements (unless, in the common case, the loop or switch
+ statement is never executed).
+
+ It is important to know that functions are not always
+ inlined even if they are declared as such; for example,
+ virtual and recursive functions are not normally inlined.
+ Usually recursive functions should not be inline. The main
+ reason for making a virtual function inline is to place its
+ definition in the class, either for convenience or to
+ document its behavior, e.g., for accessors and mutators.
+
+ The definition of an inline function needs to be in a header
+ file, so that the compiler has the definition available for
+ inlining at the call sites. However, implementation code
+ properly belongs in
+ If an inline function definition is short, with very little,
+ if any, logic in it, you should put the code in your
+
+ Another use of
+ Do not forget that a
+ Parameters to C/C++ functions are either input to the
+ function, output from the function, or both. Input parameters
+ are usually values or
+ This is not a hard-and-fast rule. Parameters that are both
+ input and output (often classes/structs) muddy the waters,
+ and, as always, consistency with related functions may require
+ you to bend the rule.
+
+
+ All of a project's header files should be
+ listed as descentants of the project's source directory
+ without use of UNIX directory shortcuts
+ In
+ The preferred ordering reduces hidden dependencies. We want
+ every header file to be compilable on its own. The easiest
+ way to achieve this is to make sure that every one of them is
+ the first
+
+ Within each section it is nice to order the includes
+ alphabetically.
+
+ For example, the includes in
+
+
+ Namespaces provide a (hierarchical) axis of naming, in
+ addition to the (also hierarchical) name axis provided by
+ classes.
+
+ For example, if two different projects have a class
+
+ Namespaces can be confusing, because they provide an
+ additional (hierarchical) axis of naming, in addition to the
+ (also hierarchical) name axis provided by classes.
+
+ Use of unnamed spaces in header files can easily cause
+ violations of the C++ One Definition Rule (ODR).
+
+ Use namespaces according to the policy described below.
+
+ However, file-scope declarations that are
+ associated with a particular class may be declared
+ in that class as types, static data members or
+ static member functions rather than as members of
+ an unnamed namespace. Terminate the unnamed
+ namespace as shown, with a comment
+ Named namespaces should be used as follows:
+
+ The typical
+ Sometimes it is useful, or even necessary, to define a
+ function not bound to a class instance. Such a function can
+ be either a static member or a nonmember function.
+ Nonmember functions should not depend on external variables,
+ and should nearly always exist in a namespace. Rather than
+ creating classes only to group static member functions which
+ do not share static data, use
+ namespaces instead.
+
+ Functions defined in the same compilation unit as production
+ classes may introduce unnecessary coupling and link-time
+ dependencies when directly called from other compilation
+ units; static member functions are particularly susceptible
+ to this. Consider extracting a new class, or placing the
+ functions in a namespace possibly in a separate library.
+
+ If you must define a nonmember function and it is only
+ needed in its
+ C++ allows you to declare variables anywhere in a function.
+ We encourage you to declare them in as local a scope as
+ possible, and as close to the first use as possible. This
+ makes it easier for the reader to find the declaration and see
+ what type the variable is and what it was initialized to. In
+ particular, initialization should be used instead of
+ declaration and assignment, e.g.
+
+ Note that gcc implements
+ There is one caveat: if the variable is an object, its
+ constructor is invoked every time it enters scope and is
+ created, and its destructor is invoked every time it goes
+ out of scope.
+
+ It may be more efficient to declare such a variable used in a
+ loop outside that loop:
+
+ Unfortunately the order in which constructors, destructors,
+ and initializers for global variables are called is only
+ partially specified and can change from build to build. This
+ can cause bugs that are very difficult to find.
+
+ Therefore we forbid global variables of class types (which
+ includes STL string, vector, etc.) because initialization
+ order might matter for their constructor, now or in the
+ future. Built-in types and structs of built-in types without
+ constructors are okay.
+
+ If you need a global variable of a class
+ type, use the
+ singleton
+ pattern.
+
+ For global string constants, use C style strings, not
+ STL strings:
+
+ Although we permit global variables in the global scope,
+ please be judicious in your use of them. Most global variables
+ should either be static data members of some class, or, if only
+ needed in one
+ Please note that
+ If your class defines member variables 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
+ and valid.
+
+ The reason for this is that if you have no other
+ constructors and do not define a default constructor, the
+ compiler will generate one for you. This compiler
+ generated constructor may not initialize your object
+ sensibly.
+
+ If your class inherits from an existing class but you add no
+ new member variables, you are not required to have a default
+ constructor.
+
+
+ We require all single argument constructors to be
+ explicit. Always put
+ The exception is copy constructors, which, in the rare
+ cases when we allow them, should probably not be
+
+ 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.
+
+ Consider adding dummy declarations for the copy constructor and
+ assignment operator in the class'
+ Then, in
+ In almost all cases your class should use the
+
+ 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
+
+
+ The
+
+ If more functionality is required, a
+ For consistency with STL, you can use
+ Note that member variables in structs and classes have
+ different naming rules.
+
+ All inheritance should be
+ Do not overuse implementation inheritance. Composition is
+ often more appropriate. Try to restrict use of inheritance
+ to the "is-a" case:
+ Make your destructor
+ Limit the use of
+ When redefining an inherited virtual function, explicitly
+ declare it
+ A class is a pure interface if it meets the following requirements:
+
+ An interface class can never be directly instantiated
+ because of the pure virtual method(s) it declares. To make
+ sure all implementations of the interface can be destroyed
+ correctly, they must also declare a virtual destructor (in
+ an exception to the first rule, this should not be pure). See
+ Stroustrup, The C++ Programming Language, 3rd
+ edition, section 12.4 for details.
+
+ In general, do not overload operators. The assignment operator
+ (
+ However, there may be rare cases where you need to overload
+ an operator to interoperate with templates or "standard" C++
+ classes (such as
+ Some of the STL algorithms do require you to overload
+
+ See also Copy Constructors
+ and Function
+ Overloading.
+
+ The definitions of accessors are usually inlined in the header
+ file.
+
+ See also Inheritance and Function Names.
+
+ Your class definition should start with its
+ Within each section, the declarations generally should be in
+ the following order:
+
+ The
+ Method definitions in the corresponding
+ Do not put large method definitions inline in the class
+ definition. Usually, only trivial or performance-critical,
+ and very short, methods may be defined inline. See Inline Functions for more
+ details.
+
+ We recognize that long functions are sometimes appropriate, so
+ no hard limit is placed on functions length. If a function
+ exceeds about 40 lines, think about whether it can be broken
+ up without harming the structure of the program.
+
+ Even if your long function works perfectly now, someone
+ modifying it in a few months may add new behavior. This could
+ result in bugs that are hard to find. Keeping your functions
+ short and simple makes it easier for other people to read and
+ modify your code.
+
+ You could find long and complicated functions when working
+ with
+
+ some
+ code. Do not be intimidated by modifying existing
+ code: if working with such a function proves to be difficult,
+ you find that errors are hard to debug, or you want to use a
+ piece of it in several different contexts, consider breaking
+ up the function into smaller and more manageable pieces.
+
+ 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 are objects that act like pointers but have
+ added semantics. When a
+ Generally speaking, we prefer that we design code with clear
+ object ownership. The clearest object ownership is obtained by
+ using an object directly as a field or local variable, without
+ using pointers at all. On the other extreme, by their very definition,
+ reference counted pointers are owned by nobody. The problem with
+ this design is that it is easy to create circular references or other
+ strange conditions that cause an object to never be deleted.
+ It is also slow to perform atomic operations every time a value is
+ copied or assigned.
+
+ Although they are not recommended, reference counted pointers are
+ sometimes the simplest and most elegant way to solve a problem.
+
+
+ Within function parameter lists all references must be
+
+ In fact it is a very strong convention that input
+ arguments are values or
+ One case when you might want an input parameter to be a
+
+ You may write a function that takes a
+
+ Friends should usually be defined in the same file so that the
+ reader does not have to look in another file to find uses of
+ the private members of a class. A common use of
+
+ Friends extend, but do not break, the encapsulation
+ boundary of a class. In some cases this is better than making
+ a member public when you want to give only one other class
+ access to it. However, most classes should interact with
+ other classes solely through their public members.
+
+ On their face, the benefits of using exceptions outweigh the
+ costs, especially in new projects. However, for existing code,
+ the introduction of exceptions has implications on all dependent
+ code. If exceptions can be propagated beyond a new project, it
+ also becomes problematic to integrate the new project into
+ existing exception-free code. Because most existing C++ code at
+ Google is not prepared to deal with exceptions, it is
+ comparatively difficult to adopt new code that generates
+ exceptions.
+
+ Given that Google's existing code is not exception-tolerant, the
+ costs of using exceptions are somewhat greater than the costs in
+ in a new project. The conversion process would be slow and
+ error-prone. We don't believe that the available alternatives to
+ exceptions, such as error codes and assertions, introduce a
+ significant burden.
+
+
+ Our advice against using exceptions is not predicated on
+ philosophical or moral grounds, but practical ones.
+
+ Because we'd like to use our open-source
+ projects at Google and it's difficult to do so if those projects
+ use exceptions, we need to advise against exceptions in Google
+ open-source projects as well.
+ Things would probably be different if we had to do it all over
+ again from scratch.
+
+ There is an exception to this
+ rule (no pun intended) for Windows code.
+
+ It is useful in some unittests. For example, it is useful in
+ tests of factory classes where the test has to verify that a
+ newly created object has the expected dynamic type.
+
+ In rare circumstances, it is useful even outside of
+ tests.
+
+ Do not use RTTI, except in unittests. If you find yourself
+ in need of writing code that behaves differently based on
+ the class of an object, consider one of the alternatives to
+ querying the type.
+
+ Virtual methods are the preferred way of executing different
+ code paths depending on a specific subclass type. This puts
+ the work within the object itself.
+
+ If the work belongs outside the object and instead in some
+ processing code, consider a double-dispatch solution, such
+ as the Visitor design pattern. This allows a facility
+ outside the object itself to determine the type of class
+ using the built-in type system.
+
+ If you think you truly cannot use those ideas,
+
+ you may use RTTI. But think twice
+ about it. :-) Then think twice again.
+ Do not hand-implement an RTTI-like workaround. The arguments
+ against RTTI apply just as much to workarounds like class
+ hierarchies with type tags.
+
+ Do not use C-style casts. Instead, use these C++-style
+ casts.
+
+
+ Do not use streams, except where required by a logging interface.
+ Use
+ There are various pros and cons to using streams, but in
+ this case, as in many other cases, consistency trumps the
+ debate. Do not use streams in your code.
+
+ There has been debate on this issue, so this explains the
+ reasoning in greater depth. Recall the Only One Way
+ guiding principle: we want to make sure that whenever we
+ do a certain type of I/O, the code looks the same in all
+ those places. Because of this, we do not want to allow
+ users to decide between using streams or using
+
+ Proponents of streams have argued that streams are the obvious
+ choice of the two, but the issue is not actually so clear. For
+ every advantage of streams they point out, there is an
+ equivalent disadvantage. The biggest advantage is that
+ you do not need to know the type of the object to be
+ printing. This is a fair point. But, there is a
+ downside: you can easily use the wrong type, and the
+ compiler will not warn you. It is easy to make this
+ kind of mistake without knowing when using streams.
+
+ The compiler does not generate an error because
+
+ Some say
+ And so on and so forth for any issue you might bring up.
+ (You could argue, "Things would be better with the right
+ wrappers," but if it is true for one scheme, is it not
+ also true for the other? Also, remember the goal is to
+ make the language smaller, not add yet more machinery that
+ someone has to learn.)
+
+ Either path would yield different advantages and
+ disadvantages, and there is not a clearly superior
+ solution. The simplicity doctrine mandates we settle on
+ one of them though, and the majority decision was on
+
+
+ However, do not go crazy with
+ The
+ Some people favor the form
+ That said, while we encourage putting
+
+
+ We use
+ For integers we know can be "big",
+ use
+
+ You should not use the unsigned integer types such as
+
+ Some people, including some textbook authors, recommend
+ using unsigned types to represent numbers that are never
+ negative. This is intended as a form of self-documentation.
+ However, in C, the advantages of such documentation are
+ outweighed by the real bugs it can introduce. Consider:
+
+ This code will never terminate! Sometimes gcc will notice
+ this bug and warn you, but often it will not. Equally bad
+ bugs can occur when comparing signed and unsigned
+ variables. Basically, C's type-promotion scheme causes
+ unsigned types to behave differently than one might expect.
+
+ So, document that a variable is non-negative using
+ assertions.
+ Don't use an unsigned type.
+
+
+ Note that the
+ Macros mean that the code you see is not the same as the code
+ the compiler sees. This can introduce unexpected behavior,
+ especially since macros have global scope.
+
+ Luckily, macros are not nearly as necessary in C++ as they are
+ in C. Instead of using a macro to inline performance-critical
+ code, use an inline function. Instead of using a macro to
+ store a constant, use a
+ Macros can do things these other techniques cannot, and you do
+ see them in the codebase, especially in the lower-level
+ libraries. And some of their special features (like
+ stringifying, concatenation, and so forth) are not available
+ through the language proper. But before using a macro,
+ consider carefully whether there's a non-macro way to achieve
+ the same result.
+
+ The following usage pattern will avoid many problems with
+ macros; if you use macros, follow it whenever possible:
+
+ Use
+ For pointers (address values), there is a choice between
+ Use
+ Use
+
+ 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.
+
+ Give as descriptive a name as possible, within reason. Do
+ not worry about saving horizontal space as it is far more
+ important to make your code immediately understandable by a
+ new reader. Examples of well-chosen names:
+
+ Poorly-chosen names use ambiguous abbreviations or arbitrary
+ characters that do not convey meaning:
+
+ Type and variable names should typically be nouns: e.g.,
+
+ Function names should typically be imperative (that is they
+ should be commands): e.g.,
+ Do not use abbreviations unless they are extremely well
+ known outside your project. For example:
+
+ Never abbreviate by leaving out letters:
+
+ Examples of acceptable file names:
+
+
+ C++ files should end in
+ Do not use filenames that already exist
+ in
+ In general, make your filenames very specific. For example,
+ use
+ Inline functions must be in a
+ See also the section -inl.h Files
+
+ The names of all types — classes, structs, typedefs, and enums
+ — have the same naming convention. Type names should start
+ with a capital letter and have a capital letter for each new
+ word. No underscores. For example:
+
+ For example:
+
+ Data members (also called instance variables or member
+ variables) are lowercase with optional underscores like
+ regular variable names, but always end with a trailing
+ underscore.
+
+ Data members in structs should be named like regular
+ variables without the trailing underscores that data members
+ in classes have.
+
+ See Structs vs. Classes for a
+ discussion of when to use a struct versus a class.
+
+ There are no special requirements for global variables,
+ which should be rare in any case, but if you use one,
+ consider prefixing it with
+ All compile-time constants, whether they are declared locally,
+ globally, or as part of a class, follow a slightly different
+ naming convention from other variables. Use a
+ Functions should start with a capital letter and have a
+ capital letter for each new word. No underscores:
+
+ Accessors and mutators (get and set functions) should match
+ the name of the variable they are getting and setting. This
+ shows an excerpt of a class whose instance variable is
+
+ You may also use lowercase letters for other very short
+ inlined functions. For example if a function were so cheap
+ you would not cache the value if you were calling it in a
+ loop, then lowercase naming would be acceptable.
+
+ See Namespaces for a discussion of
+ namespaces and how to name them.
+
+ The individual enumerators should be all uppercase. The
+ enumeration name,
+ Please see the description of
+ macros; in general macros should not be used.
+ However, if they are absolutely needed, then they should be
+ named like enum value names with all capitals and underscores.
+
+
+Craig Silverstein
+Gregory Eitzmann
+Mark Mentovai
+Tashana Landray
+
+.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.
+ #define guards to
+ prevent multiple inclusion. The format of the symbol name
+ should be
+ <PROJECT>_<PATH>_<FILE>_H_.
+ foo/src/bar/baz.h in project foo should
+ have the following guard:
+ #include in .h files.
+ 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".
+ Foo in a header file
+ without access to its definition?
+
+
+ Foo* or
+ Foo&.
+ Foo.
+ Foo. This is because static data members
+ are defined outside the class definition.
+ Foo if your class subclasses Foo or
+ has a data member of type Foo.
+ 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.
+ .cc files typically do require the
+ definitions of the classes they use, and usually have to
+ include several header files.
+ -inl.h suffix to define
+ complex inline functions when needed.
+ .cc files, and we do not like
+ to have much actual code in .h files unless there
+ is a readability or performance advantage.
+ .h file. For example, accessors and mutators
+ should certainly be inside a class definition. More complex
+ inline functions may also be put in a .h file for
+ the convenience of the implementer and callers, though if this
+ makes the .h file too unwieldy you can instead
+ put that code in a separate -inl.h file.
+ This separates the implementation from the class definition,
+ while still allowing the implementation to be included where
+ necessary.
+ -inl.h files is for definitions of
+ function templates. This can be used to keep your template
+ definitions easy to read.
+ -inl.h file requires a
+ #define guard just
+ like any other header file.
+ const references, while output
+ and input/output parameters will be non-const
+ pointers. When ordering function parameters, put all input-only
+ parameters before any output parameters. In particular, do not add
+ new parameters to the end of the function just because they are
+ new; place new input-only parameters before the output
+ parameters.
+ .h, your
+ project's
+ .h.
+ . (the current
+ directory) or .. (the parent directory). For
+ example,
+
+ google-awesome-project/src/base/logging.h
+ should be included as
+ dir/foo.cc, whose main purpose is
+ to implement or test the stuff in
+ dir2/foo2.h, order your includes as
+ follows:
+
+
+ dir2/foo2.h (preferred location
+ — see details below)..h files..h files..h file #included in some
+ .cc.
+ dir/foo.cc and
+ dir2/foo2.h are often in the same
+ directory (e.g. base/basictypes_unittest.cc and
+ base/basictypes.h), but can be in different
+ directories too.
+ google-awesome-project/src/foo/internal/fooserver.cc
+ might look like this:
+ .cc files are encouraged. With
+ named namespaces, choose the name based on the
+
+ project, and possibly its path.
+ Do not use a Foo in the global scope, these symbols may
+ collide at compile time or at runtime. If each project
+ places their code in a namespace, project1::Foo
+ and project2::Foo are now distinct symbols that
+ do not collide.
+
+
+ .cc files, to avoid runtime naming
+ conflicts:
+ //
+ namespace.
+ .h
+ files.
+
+
+ .cc file might have more
+ complex detail, including the need to reference classes
+ in other namespaces.
+ std, not even forward declarations of
+ standard library classes. Declaring entities in
+ namespace std is undefined behavior,
+ i.e., not portable. To declare entities from the
+ standard library, include the appropriate header
+ file.
+ .cc file, and in functions,
+ methods or classes in .h files.
+ .cc file, and in functions and methods in
+ .h files.
+ .cc file to avoid including the nested class
+ definition in the enclosing class declaration, since the
+ nested class definition is usually only relevant to the
+ implementation.
+ Foo::Bar* pointer will have to
+ include the full class declaration for Foo.
+ .cc file, use an unnamed
+ namespace or static
+ linkage (eg static int Foo() {...}) to limit
+ its scope.
+ for (int i = 0; i
+ < 10; ++i) correctly (the scope of i is
+ only the scope of the for loop), so you can then
+ reuse i in another for loop in the
+ same scope. It also correctly scopes declarations in
+ if and while statements, e.g.
+ const
+ globals are forbidden in threaded code. Global variables should
+ never be initialized with the return value of a function.
+ .cc file, defined in an unnamed
+ namespace. (As an alternative to using
+ an unnamed namespace, you can use static linkage to
+ limit the variable's scope.)
+ static class member variables
+ count as global variables, and should not be of class types!
+ Init() method for non-trivial
+ initialization.
+
+
+ main(), possibly breaking some implicit
+ assumptions in the constructor code. For instance,
+
+ gflags
+ will not yet have been initialized.
+ Init() method and/or adding a
+ member flag that indicates whether the object was successfully
+ initialized.
+ new a
+ class object with no arguments. It is always called when
+ calling new[] (for arrays).
+ explicit for constructors with
+ one argument.
+ Foo::Foo(string name) and then pass a string to a
+ function that expects a Foo, the constructor will
+ be called to convert the string into a Foo and
+ will pass the Foo to your function for you. This
+ can be convenient but is also a source of trouble when things
+ get converted and new objects created without you meaning them
+ to. Declaring a constructor explicit prevents it
+ from being invoked implicitly as a conversion.
+ explicit in front of
+ one-argument constructors in the class definition:
+ explicit Foo(string name);
+ explicit.
+
+ Classes that are intended to be
+ transparent wrappers around other classes are also
+ exceptions.
+ Such exceptions should be clearly marked with comments.
+ DISALLOW_COPY_AND_ASSIGN.
+ 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:
+ class Foo:
+ 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=.
+ std::tr1::shared_ptr.
+ struct only for passive objects that carry data;
+ everything else is a class.
+ struct and class keywords behave
+ almost identically in C++. We add our own semantic meanings
+ to each keyword, so you should use the appropriate keyword for
+ the data-type you're defining.
+ structs should be used for passive objects that carry
+ data, and may have associated constants, but lack any functionality
+ other than access/setting the data members. The
+ accessing/setting of fields is done by directly accessing the
+ fields rather than through method invocations. Methods should
+ not provide behavior but should only be used to set up the
+ data members, e.g., constructor, destructor,
+ Initialize(), Reset(),
+ Validate().
+ class is more
+ appropriate. If in doubt, make it a class.
+ struct
+ instead of class for functors and traits.
+ public.
+ public. If you want to
+ do private inheritance, you should be including an instance of
+ the base class as a member instead.
+ Bar subclasses
+ Foo if it can reasonably be said that
+ Bar "is a kind of" Foo.
+ virtual if necessary. If
+ your class has virtual methods, its destructor
+
+ should be virtual.
+ protected to those member
+ functions that might need to be accessed from subclasses.
+ Note that data members must always
+ be private.
+ virtual in the declaration of the
+ derived class. Rationale: If virtual is
+ omitted, the reader has to check all ancestors of the
+ class in question to determine if the function is virtual
+ or not.
+ Interface suffix.
+ Interface suffix.
+ Interface suffix.
+
+
+ = 0") methods
+ and static methods (but see below for destructor).
+ Interface suffix.
+ Interface suffix lets
+ others know that they must not add implemented methods or non
+ static data members. This is particularly important in the case of
+ multiple inheritance.
+ Additionally, the interface concept is already well-understood by
+ Java programmers.
+ Interface suffix lengthens the class name, which
+ can make it harder to read and understand. Also, the interface
+ property may be considered an implementation detail that shouldn't
+ be exposed to clients.
+ Interface only if it meets the
+ above requirements. We do not require the converse, however:
+ classes that meet the above requirements are not required to end
+ with Interface.
+ + and
+ / operate on the class as if it were a built-in
+ type.
+ int). Overloaded operators are more playful
+ names for functions that are less-colorfully named, such as
+ Equals() or Add(). For some
+ template functions to work correctly, you may need to define
+ operators.
+
+
+ Overloading also has surprising ramifications. For instance,
+ you can't forward declare classes that overload
+ Equals() is much
+ easier than searching for relevant invocations of
+ ==.
+ Foo + 4 may do one thing,
+ while &Foo + 4 does something totally
+ different. The compiler does not complain for either of
+ these, making this very hard to debug.
+ operator&.
+ operator=), in particular, is insidious and
+ should be avoided. You can define functions like
+ Equals() and CopyFrom() if you need
+ them.
+ operator<<(ostream&, const
+ T&) for logging). These are acceptable if fully
+ justified, but you should try to avoid these whenever
+ possible. In particular, do not overload operator==
+ or operator< just so that your class can be
+ used as a key in an STL container; instead, you should
+ create equality and comparison functor types when declaring
+ the container.
+ operator==, and you may do so in these cases,
+ provided you document why.
+ 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().
+ public: before private:, methods
+ before data members (variables), etc.
+ public:
+ section, followed by its protected: section and
+ then its private: section. If any of these sections
+ are empty, omit them.
+
+
+ DISALLOW_COPY_AND_ASSIGN macro invocation
+ should be at the end of the private: section. It
+ should be the last thing in the class. See Copy Constructors.
+ .cc file
+ should be the same as the declaration order, as much as possible.
+ scoped_ptr
+ is great. You should only use std::tr1::shared_ptr
+ under very specific conditions, such as when objects need to be
+ held by STL containers. You should never use auto_ptr.
+ scoped_ptr is
+ destroyed, for instance, it deletes the object it's pointing
+ to. shared_ptr is the same way, but implements
+ reference-counting so only the last pointer to an object
+ deletes it.
+ const.
+ int foo(int
+ *pval). In C++, the function can alternatively
+ declare a reference parameter: int foo(int
+ &val).
+ (*pval)++. Necessary for some applications like
+ copy constructors. Makes it clear, unlike with pointers, that
+ NULL is not a possible value.
+ const:
+ const references while
+ output arguments are pointers. Input parameters may be
+ const pointers, but we never allow
+ non-const reference parameters.
+ const pointer is if you want to emphasize that the
+ argument is not copied, so it must exist for the lifetime of the
+ object; it is usually best to document this in comments as
+ well. STL adapters such as bind2nd and
+ mem_fun do not permit reference parameters, so
+ you must declare functions with pointer parameters in these
+ cases, too.
+ const string& and overload it with another that
+ takes const char*.
+ AppendString(), AppendInt() rather
+ than just Append().
+ alloca().
+ alloca() are very
+ efficient.
+ scoped_ptr/scoped_array.
+ friend classes and functions,
+ within reason.
+ friend is to have a FooBuilder class
+ be a friend of Foo so that it can construct the
+ inner state of Foo correctly, without exposing
+ this state to the world. In some cases it may be useful to
+ make a unittest class a friend of the class it tests.
+
+
+ Init() method, but these require heap
+ allocation or a new "invalid" state, respectively.
+
+ throw statement to an existing
+ function, you must examine all of its transitive callers. Either
+ they must make at least the basic exception safety guarantee, or
+ they must never catch the exception and be happy with the
+ program terminating as a result. For instance, if
+ f() calls g() calls
+ h(), and h throws an exception
+ that f catches, g has to be
+ careful or it may not clean up properly.static_cast<>(). Do not use
+ other cast formats like int y = (int)x; or
+ int y = int(x);.
+ (int)3.5) and sometimes you are doing a
+ cast (e.g., (int)"hello"); C++ casts
+ avoid this. Additionally C++ casts are more visible when
+ searching for them.
+
+
+
+ static_cast as the equivalent of a
+ C-style cast that does value conversion, or when you need to explicitly up-cast
+ a pointer from a class to its superclass.
+ const_cast to remove the const
+ qualifier (see const).
+ reinterpret_cast to do unsafe
+ conversions of pointer types to and from integer and
+ other pointer types. Use this only if you know what you are
+ doing and you understand the aliasing issues.
+
+ dynamic_cast except in test code.
+ If you need to know type information at runtime in this way
+ outside of a unittest, you probably have a design
+ flaw.
+ printf() and
+ scanf().
+ printf either.) Streams
+ have automatic constructors and destructors that open and close the
+ relevant files.
+ pread(). Some formatting (particularly the common
+ format string idiom %.*s) is difficult if not
+ impossible to do efficiently using streams without using
+ printf-like hacks. Streams do not support operator
+ reordering (the %1s directive), which is helpful for
+ internationalization.
+ printf-like routines instead.
+ printf plus Read/Write/etc. Instead, we should
+ settle on one or the other. We made an exception for logging
+ because it is a pretty specialized application, and for
+ historical reasons.
+ << has been overloaded. We discourage
+ overloading for just this reason.
+ printf formatting is ugly and hard to
+ read, but streams are often no better. Consider the following
+ two fragments, both with the same typo. Which is easier to
+ discover?
+ printf + read/write.
+ ++i) of the increment and
+ decrement operators with iterators and other template objects.
+ ++i or
+ i++) or decremented (--i or
+ i--) and the value of the expression is not used,
+ one must decide whether to preincrement (decrement) or
+ postincrement (decrement).
+ ++i) is never less efficient than the "post"
+ form (i++), and is often more efficient. This is
+ because post-increment (or decrement) requires a copy of
+ i to be made, which is the value of the
+ expression. If i is an iterator or other
+ non-scalar type, copying i could be expensive.
+ Since the two types of increment behave the same when the
+ value is ignored, why not just always pre-increment?
+ for
+ loops. Some find post-increment easier to read, since the
+ "subject" (i) precedes the "verb" (++),
+ just like in English.
+ const whenever
+ it makes sense to do so.
+ const to indicate the variables are not
+ changed (e.g., const int foo). Class functions
+ can have the const qualifier to indicate the
+ function does not change the state of the class member
+ variables (e.g., class Foo { int Bar(char c) const;
+ };).
+ const is viral: if you pass a const
+ variable to a function, that function must have const
+ in its prototype (or the variable will need a
+ const_cast). This can be a particular problem
+ when calling library functions.
+ const variables, data members, methods and
+ arguments add a level of compile-time type checking; it
+ is better to detect errors as soon as possible.
+ Therefore we strongly recommend that you use
+ const whenever it makes sense to do so:
+
+
+ const.
+ const whenever
+ possible. Accessors should almost always be
+ const. Other methods should be const if they do
+ not modify any data members, do not call any
+ non-const methods, and do not return a
+ non-const pointer or non-const
+ reference to a data member.
+ const
+ whenever they do not need to be modified after
+ construction.
+ const. Something like
+ const int * const * const x; is likely
+ overkill, even if it accurately describes how const x is.
+ Focus on what's really useful to know: in this case,
+ const int** x is probably sufficient.
+ mutable keyword is allowed but is unsafe
+ when used with threads, so thread safety should be carefully
+ considered first.
+ int const *foo to
+ const int* foo. They argue that this is more
+ readable because it's more consistent: it keeps the rule
+ that const always follows the object it's
+ describing. However, this consistency argument doesn't
+ apply in this case, because the "don't go crazy" dictum
+ eliminates most of the uses you'd have to be consistent with.
+
+ Putting the const first is arguably more readable,
+ since it follows English in putting the "adjective"
+ (const) before the "noun" (int).
+ const first,
+ we do not require it. But be consistent with the code around
+ you!
+ int. If a program needs a variable of a different
+ size, use
+
+ a precise-width integer type from
+ <stdint.h>, such as int16_t.
+ short is 16 bits,
+ int is 32 bits, long is 32 bits and
+ long long is 64 bits.
+ <stdint.h> defines
+ types like int16_t, uint32_t,
+ int64_t, etc.
+ You should always use those in preference to
+ short, unsigned long long and the
+ like, when you need a guarantee on the size of an integer.
+ Of the C integer types, only int should be
+ used. When appropriate, you are welcome to use standard
+ types like size_t and ptrdiff_t.
+ int very often, for integers we know are not
+ going to be too big, e.g., loop counters. Use plain old
+ int for such things. You should assume that an
+ int is
+
+ at least 32 bits,
+ but don't assume that it has more than 32 bits.
+ If you need a 64-bit integer type, use
+ int64_t or
+ uint64_t.
+ int64_t.
+
+ uint32_t,
+ unless the quantity you are representing is really a bit pattern
+ rather than a number. In particular, do not use unsigned types to
+ say a number will never be negative. Instead, use
+
+ assertions for this.
+
+
+
+ printf() specifiers for some types are
+ not cleanly portable between 32-bit and 64-bit
+ systems. C99 defines some portable format
+ specifiers. Unfortunately, MSVC 7.1 does not
+ understand some of these specifiers and the
+ standard is missing a few, so we have to define our
+ own ugly versions in some cases (in the style of the
+ standard include file inttypes.h):
+
+
+
+
+
+ Type
+ DO NOT use
+ DO use
+ Notes
+
+
+
+
+ void * (or any pointer)
+ %lx
+ %p
+
+
+
+
+ int64_t
+ %qd,
+ %lld
+ %"PRId64"
+
+
+
+
+ uint64_t
+ %qu,
+ %llu,
+ %llx
+ %"PRIu64",
+ %"PRIx64"
+
+
+
+ size_t
+ %u
+ %"PRIuS",
+ %"PRIxS"C99 specifies
+ %zu
+
+
+
+
+ ptrdiff_t
+ %d
+ %"PRIdS"C99 specifies
+ %zdPRI* macros expand to independent
+ strings which are concatenated by the compiler. Hence
+ if you are using a non-constant format string, you
+ need to insert the value of the macro into the format,
+ rather than the name. It is still possible, as usual,
+ to include length specifiers, etc., after the
+ % when using the PRI*
+ macros. So, e.g. printf("x = %30"PRIuS"\n",
+ x) would expand on 32-bit Linux to
+ printf("x = %30" "u" "\n", x), which the
+ compiler will treat as printf("x = %30u\n",
+ x).
+ sizeof(void *) !=
+ sizeof(int). Use intptr_t if
+ you want a pointer-sized integer.
+ int64_t/uint64_t
+ member will by default end up being 8-byte aligned on a 64-bit
+ system. If you have such structures being shared on disk
+ between 32-bit and 64-bit code, you will need to ensure
+ that they are packed the same on both architectures.
+
+ Most compilers offer a way to alter
+ structure alignment. For gcc, you can use
+ __attribute__((packed)). MSVC offers
+ #pragma pack() and
+ __declspec(align()).
+ LL or ULL suffixes as
+ needed to create 64-bit constants. For example:
+
+ #ifdef _LP64 to choose between
+ the code variants. (But please avoid this if
+ possible, and keep any such changes localized.)
+ const variables to macros.
+ const variable. Instead of
+ using a macro to "abbreviate" a long variable name, use a
+ reference. Instead of using a macro to conditionally compile code
+ ... well, don't do that at all (except, of course, for the
+ #define guards to prevent double inclusion of
+ header files). It makes testing much more difficult.
+
+
+
+ .h file.
+ #define macros right before you use them,
+ and #undef them right after.
+ #undef an existing macro before
+ replacing it with your own; instead, pick a name that's
+ likely to be unique.
+ 0 for integers, 0.0 for reals,
+ NULL for pointers, and '\0' for chars.
+ 0 for integers and 0.0 for reals.
+ This is not controversial.
+ 0
+ and NULL. Bjarne Stroustrup prefers an unadorned
+ 0. We prefer NULL because it looks like a
+ pointer. In fact, some C++ compilers, such as gcc 4.1.0, provide special
+ definitions of NULL which enable them to give useful
+ warnings, particularly in situations where sizeof(NULL)
+ is not equal to sizeof(0).
+ '\0' for chars.
+ This is the correct type and also makes code more readable.
+ sizeof(varname) instead of
+ sizeof(type) whenever possible.
+ sizeof(varname) because it will update
+ appropriately if the type of the variable changes.
+ sizeof(type) may make sense in some cases,
+ but should generally be avoided because it can fall out of sync if
+ the variable's type changes.
+ boost/compressed_pair.hpp is permitted. We are actively
+ considering adding other Boost features to the list, so this rule
+ may be relaxed in the future.
+ FileOpener,
+
+ num_errors.
+ OpenFile(),
+ set_num_errors(). There is an exception for
+ accessors, which, described more completely in Function Names, should be named
+ the same as the variable they access.
+ _) or dashes (-). Follow the
+ convention that your
+
+ project
+ uses.
+
+ my_useful_class.cc
+
+ my-useful-class.cc
+ myusefulclass.cc
+ .cc and header files
+ should end in .h.
+ /usr/include, such as db.h.
+ http_server_logs.h rather
+ than logs.h. A very common case is to have a
+ pair of files called, e.g., foo_bar.h
+ and foo_bar.cc, defining a class
+ called FooBar.
+ .h file. If your
+ inline functions are very short, they should go directly into your
+ .h file. However, if your inline functions
+ include a lot of code, they may go into a third file that
+ ends in -inl.h. In a class with a lot of inline
+ code, your class could have three files:
+ MyExcitingClass, MyExcitingEnum.
+ my_exciting_local_variable,
+ my_exciting_member_variable_.
+ g_ or some other
+ marker to easily distinguish it from local variables.
+ k followed by mixed case:
+ kDaysInAWeek.
+ k
+ followed by words with uppercase first letters:
+ MyExcitingFunction(),
+ MyExcitingMethod(),
+ my_exciting_member_variable(),
+ set_my_exciting_member_variable().
+ num_entries_.
+ google_awesome_project.
+ MY_EXCITING_ENUM_VALUE.
+ UrlTableErrors, is a type, and
+ therefore mixed case.
+ MY_MACRO_THAT_SCARES_SMALL_CHILDREN.
+
+
+ bigopen() open() uint typedef bigpos struct or class, follows form of
+ pos sparse_hash_map LONGLONG_MAX INT_MAX
+ 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! +
+ + + +// or /* */ syntax, as long
+ as you are consistent.
+
+ You can use either the // or the /* */
+ syntax; however, // is much more common.
+ Be consistent with how you comment and what style you use where.
+
+ Every file should contain the following items, in order: +
Copyright 2008 Google Inc.)+ If you make significant changes to a file that someone else + originally wrote, add yourself to the author line. This can + be very helpful when another + + contributor + has questions about the file and needs to know whom to contact + about it. +
++ Every file should have a comment at the top, below the + and author line, that describes the contents of the file. +
+
+ Generally a .h file will describe the classes
+ that are declared in the file with an overview of what they
+ are for and how they are used. A .cc file
+ should contain more information about implementation details
+ or discussions of tricky algorithms. If you feel the
+ implementation details or a discussion of the algorithms
+ would be useful for someone reading the .h,
+ feel free to put it there instead, but mention in the
+ .cc that the documentation is in the
+ .h file.
+
+ Do not duplicate comments in both the .h and
+ the .cc. Duplicated comments diverge.
+
+ If you have already described a class in detail in the + comments at the top of your file feel free to simply state + "See comment at top of file for a complete description", but + be sure to have some sort of comment. +
++ Document the synchronization assumptions the class makes, if + any. If an instance of the class can be accessed by multiple + threads, take extra care to document the rules and invariants + surrounding multithreaded use. +
+ ++ Every function declaration should have comments immediately + preceding it that describe what the function does and how to + use it. These comments should be descriptive ("Opens the + file") rather than imperative ("Open the file"); the comment + describes the function, it does not tell the function what + to do. In general, these comments do not describe how the + function performs its task. Instead, that should be left to + comments in the function definition. +
++ Types of things to mention in comments at the function + declaration: +
+NULL.
+ + Here is an example: +
++ However, do not be unnecessarily verbose or state the + completely obvious. Notice below that it is not necessary + to say "returns false otherwise" because this is implied. +
++ When commenting constructors and destructors, remember that + the person reading your code knows what constructors and + destructors are for, so comments that just say something like + "destroys this object" are not useful. Document what + constructors do with their arguments (for example, if they + take ownership of pointers), and what cleanup the destructor + does. If this is trivial, just skip the comment. It is + quite common for destructors not to have a header comment. +
++ Each function definition should have a comment describing + what the function does and anything tricky about how it does + its job. For example, in the definition comment you might + describe any coding tricks you use, give an overview of the + steps you go through, or explain why you chose to implement + the function in the way you did rather than using a viable + alternative. For instance, you might mention why it must + acquire a lock for the first half of the function but why it + is not needed for the second half. +
+
+ Note you should not just repeat the comments given
+ with the function declaration, in the .h file or
+ wherever. It's okay to recapitulate briefly what the function
+ does, but the focus of the comments should be on how it does it.
+
+ Each class data member (also called an instance variable or
+ member variable) should have a comment describing what it is
+ used for. If the variable can take sentinel values with
+ special meanings, such as NULL or -1, document this.
+ For example:
+
+ As with data members, all global variables should have a + comment describing what they are and what they are used for. + For example: +
++ Tricky or complicated code blocks should have comments + before them. Example: +
++ Also, lines that are non-obvious should get a comment at the + end of the line. These end-of-line comments should be + separated from the code by 2 spaces. Example: +
++ Note that there are both comments that describe what the + code is doing, and comments that mention that an error has + already been logged when the function returns. +
++ If you have several comments on subsequent lines, it can + often be more readable to line them up: +
+
+ When you pass in NULL, boolean, or literal integer
+ values to functions, you should consider adding a comment about
+ what they are, or make your code self-documenting by using
+ constants. For example, compare:
+
+ versus: +
++ Or alternatively, constants or self-describing variables: +
++ Note that you should never describe the code + itself. Assume that the person reading the code knows C++ + better than you do, even though he or she does not know what + you are trying to do: +
++ Comments should usually be written as complete + sentences with proper capitalization and periods at the end. + Shorter comments, such as comments at the end of a line of + code, can sometimes be less formal, but you should be + consistent with your style. Complete sentences are more + readable, and they provide some assurance that the comment is + complete and not an unfinished thought. +
++ Although it can be frustrating to have a code reviewer point + out that you are using a comma when you should be using a + semicolon, it is very important that source code maintain a + high level of clarity and readability. Proper punctuation, + spelling, and grammar help with that goal. +
+ +TODO comments for code that is temporary, a
+ short-term solution, or good-enough but not perfect.
+
+ TODOs should include the string TODO in
+ all caps, followed by your
+
+ name, e-mail address, or other
+ identifier
+ in parentheses. A colon is optional. The main purpose is to have
+ a consistent TODO format searchable by the person
+ adding the comment (who can provide more details upon request). A
+ TODO is not a commitment to provide the fix yourself.
+
+ If your TODO is of the form "At a future date do
+ something" make sure that you either include a very specific
+ date ("Fix by November 2005") or a very specific event
+ ("Remove this code when all clients can handle XML responses.").
+
+ 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. +
+ + ++ We recognize that this rule is controversial, but so much existing + code already adheres to it, and we feel that consistency is + important. +
++ + 80 characters is the maximum. +
++ Exception: if a comment line contains an example command or + a literal URL longer than 80 characters, that line may be + longer than 80 characters for ease of cut and paste. +
+
+ Exception: an #include statement with a long
+ path may exceed 80 columns. Try to avoid situations where this
+ becomes necessary.
+
+ Exception: you needn't be concerned about + header guards + that exceed the maximum length. + +
+
+ You shouldn't hard-code user-facing text in source, even English,
+ so use of non-ASCII characters should be rare. However, in certain
+ cases it is appropriate to include such words in your code. For
+ example, if your code parses data files from foreign
+
+
+ it may be appropriate to hard-code the non-ASCII string(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 such
+ cases, you should use UTF-8, since that is
+
+ an encoding understood by most tools able
+ to handle more than just ASCII.
+ Hex encoding is also OK, and encouraged where it enhances
+ readability — for example, "\xEF\xBB\xBF" is the
+ Unicode zero-width no-break space character, which would be
+ invisible if included in the source as straight UTF-8.
+
+ We use spaces for indentation. Do not use tabs in your code. + You should set your editor to emit spaces when you hit the tab + key. +
+ ++ Functions look like this: +
++ If you have too much text to fit on one line: +
++ or if you cannot fit even the first parameter: +
++ Some points to note: +
+
+ If your function is const, the const
+ keyword should be on the same line as the last parameter:
+
+ If some parameters are unused, comment out the variable name in the + function definition: +
++ Function calls have the following format: +
++ If the arguments do not all fit on one line, they should be + broken up onto multiple lines, with each subsequent line + aligned with the first argument. Do not add spaces after the + open paren or before the close paren: +
++ If the function has many arguments, consider having one per + line if this makes the code more readable: +
++ If the function signature is so long that it cannot fit within + the maximum line length, you may + place all arguments on subsequent lines: +
+else
+ keyword belongs on a new line.
+ + There are two acceptable formats for a basic conditional + statement. One includes spaces between the parentheses and the + condition, and one does not. +
++ The most common form is without spaces. Either is fine, but + be consistent. If you are modifying a 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 in doubt and you have no personal preference, + do not add the spaces. +
++ If you prefer you may add spaces inside the + parentheses: +
+
+ Note that in all cases you must have a space between the
+ if and the open parenthesis. You must also have
+ a space between the close parenthesis and the curly brace, if
+ you're using one.
+
+ Short conditional 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 the
+ else clause.
+
+ This is not allowed if the if statement has an
+ else:
+
+ In general, curly braces are not required for single-line
+ statements, but they are allowed if you like them. Some
+
+
+ require that an if must always always have an
+ accompanying brace.
+
+ However, if one part of an if-else
+ statement uses curly braces, the other part must too:
+
{} or continue.
+
+ case blocks in switch statements can have
+ curly braces or not, depending on your preference. If you do
+ include curly braces they should be placed as shown below.
+
+ If not conditional on an enumerated value, switch statements
+ should always have a default case (in the case of
+ an enumerated value, the compiler will warn you if any values
+ are not handled). If the default case should never execute,
+ simply
+ assert:
+
+ Empty loop bodies should use {} or
+ continue, but not a single semicolon.
+
+ The following are examples of correctly-formatted pointer and + reference expressions: +
++ Note that: +
+* or
+ &.
+ + When declaring a pointer variable or argument, you may place + the asterisk adjacent to either the type or to the variable + name: +
++ You should do this consistently within a single file or + + + so when modifying an existing file, use the style in that + file. +
+ ++ In this example, the logical AND operator is always at the end + of the lines: +
+
+ Note that both of the && logical AND
+ operators are the end of the line. Feel free to insert extra
+ parentheses judiciously, because they can be very helpful in
+ increasing readability when used appropriately.
+
return expression with parentheses.
+ + Return values should not have parentheses: +
+= or ().
+
+ You may choose between = and (); the
+ following are all correct:
+
+ Even when pre-processor directives are within the body of + indented code, the directives should start at the beginning of + the line. +
+public, protected and
+ private order, each indented one space.
+ + The basic format for a class declaration (lacking the + comments, see Class Comments for + a discussion of what comments are needed) is: +
++ Things to note: +
+public:, protected:, and
+ private: keywords should be indented one
+ space.
+ public section should be first, followed by
+ the protected and finally the
+ private section.
+ + There are two acceptable formats for initializer lists: +
++ or +
++ Namespaces do not add an extra level of + indentation. For example, use: +
++ Do not indent within a namespace: +
++ Adding trailing whitespace can cause extra work for others editing + the same file, when they merge, as can removing existing trailing + whitespace. So: Don't introduce trailing whitespace. Remove it + if you're already changing that line, or do it in a separate + clean-up + + operation (preferably when no-one else + is working on the file). +
++ This is more a principle than a rule: don't use blank lines + when you don't have to. In particular, don't put more than + one or two blank lines between functions, don't start or end + functions with a blank line, and be discriminating with your + use of blank lines inside functions. +
++ The basic principle is: The more code that fits on one screen, + the easier it is to follow and understand the control flow of + the program. Of course, readability can suffer from code + being too dense as well as too spread out, so use your + judgement. But in general, minimize use of vertical + whitespace. +
+
+ Don't start or end functions with blank lines:
+
+ Don't start and end blocks with blank lines either:
+
+ The coding conventions described above are mandatory. However, + like all good rules, these sometimes have exceptions, which we + discuss here. +
+ + + ++ If you find yourself modifying code that was written to + specifications other than those presented by this guide, you may + have to diverge from these rules in order to stay consistent with + the local conventions in that code. If you are in doubt about + how to do this, ask the original author or the person currently + responsible for the code. Remember that consistency + includes local consistency, too. +
+ ++ It is worth reiterating a few of the guidelines that you might + forget if you are used to the prevalent Windows style: +
+iNum). Use the Google naming conventions,
+ including the .cc extension for source files.
+ 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.
+ #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.
+ #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: +
+_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.)
+ 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.h and contain only macros, do not need
+ to conform to these style guidelines.
+ + 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! +
+ tag for bits of code and for variables and objects. */
+code,samp,var {
+ color: #005000;
+ font-size: 110%;
+}
+
+PRE {
+ margin-left: 2%;
+ font-size: 10pt;
+ display: block;
+ color: #005000;
+ background-color: #fbfefb;
+ border-color: #fafffa;
+ border-left-width: 1px;
+ border-right-width: 0px;
+ border-top-width: 0px;
+ border-bottom-width: 0px;
+ border-style: solid;
+ border-top: 1px solid #fffaff;
+ border-left: 1px solid #fffaff;
+ border-right: 1px dotted #eff0ef;
+ border-bottom: 1px dotted #eff0ef;
+ padding-left: 12px;
+ padding-right: 12px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+PRE {
+ -moz-border-radius: 12px;
+}
+
+PRE.badcode {
+ color: #CC0000;
+ background-color: #fffcfc;
+ border-right: 1px solid #f0efef;
+ border-bottom: 1px solid #f0efef;
+ border-top: 1px dotted #faffff;
+ border-left: 1px dotted #faffff;
+}
+
+TABLE {
+ border-collapse: collapse;
+ border-color: #dddddd;
+ border-style: dotted;
+}
+
+TD {
+ border-color: #bbbbbb;
+ border-style: solid;
+ border-width: thin
+}
+
+TH {
+ border-collapse: collapse;
+ border-color: #dddddd;
+ border-style: none;
+ border-width: thin;
+ color: #444444;
+ font-family: sans-serif;
+}
+
+address {
+ text-align: right;
+}
+
+.stylepoint_section {
+ color: #5588ff;
+ font-family: sans-serif;
+ font-size: 90%;
+ font-weight: bold;
+ margin-left: -2%;
+}
+
+.stylepoint_subsection {
+ color: #667799;
+ font-family: sans-serif;
+ font-size: 90%;
+ font-weight: bold;
+ margin-left: -1%;
+}
+
+.showhide_button {
+ border-color: #dddddd;
+ border-style: outset;
+ border-width: medium;
+ cursor: pointer;
+ font-family: sans-serif;
+}
+
+
+.link_button {
+ background-color: #ffffd0;
+ border-color: #fcfca0;
+ border-style: solid;
+ border-width: 1px;
+ font-family: sans-serif;
+ font-size: 75%;
+ font-variant: small-caps;
+ margin-left: -2%;
+ padding-left: 1px;
+ padding-right: 1px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+.toc {
+ background-color: #fcfcff;
+ padding-left: 12px;
+ padding-right: 12px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+.toc_title {
+ font-family: sans-serif;
+ font-size: 110%;
+ font-weight: 700;
+}
+
+.toc_category {
+ margin-left: 5%;
+ font-family: sans-serif;
+}
+
+.toc_stylepoint {
+ margin-left: 5%;
+ font-family: sans-serif;
+ font-size: 90%;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
diff --git a/styleguide.xsl b/styleguide.xsl
new file mode 100644
index 0000000..902e916
--- /dev/null
+++ b/styleguide.xsl
@@ -0,0 +1,501 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+ Overview
+
+
+
+
+ Parting Words
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javascript:ShowHideByName('
+
+ ','
+
+ ')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ display: inline
+ display: none
+
+
+
+
+
+
+
+
+
+
+
+ Definition:
+
+
+
+
+
+
+
+ Pros:
+
+
+
+
+
+
+
+ Cons:
+
+
+
+
+
+
+
+ Decision:
+
+
+
+
+
+
+
+ TODO:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+