C++ Style Guide

Programming style is one of the holy wars of computer programming. However, regardless of your tastes one thing is certain: when in Rome, do as the Romans do. That is, learning the accepted style of a programming language is just as important as learning the language itself.

It seems that every company or group has its own style guidelines (e.g., the linux kernel C guide, the Google C++ style guide, or the Mozilla coding style guide). Regardless, for consistency's sake, we'll stick to a set of common rules for our code. You won't lose points for a few small style violations; it's only if your files flagrantly violate style that you will lose points.

(This guide borrows heavily from the OCaml style guide for old iterations of CIS 500.)

Indentation and Spacing

  1. 80 Column Limit: No line of code can have more than 80 columns. Using more than 80 columns causes your code to wrap around to the next line which is devastating to the readability of your code.
  2. No Tab Characters: Do not use the tab character (0x09). Instead, use spaces to control indenting. Ensure that your editor of choice uses spaces when you insert a tab (i.e., soft tabs).
  3. Indent Two or Four Spaces: Most lines that indent code should only indent by two or four spaces more than the previous line of code. Pick one and be consistent.
  4. Line Breaks: Obviously the best way to stay within the 80 character limit imposed by the rule above is pressing the enter key every once and a while. Including empty lines should only be done between declarations (e.g., class definitions or field/method definitions within classes) and should be restricted to a single empty line at most.

    If a declaration or expression extends over 80 characters, indent to the opening delimeter of the declaration or expression. For example

    bool LargeMethod(FirstVeryLargeParamterType t1,
                     SecondVeryLargeParameterType t2,
                     ShortThirdParameterType t3)
    {
        return (SomeBooleanFunction(t1, t2)    ||
                AnotherBooleanFunction(t2, t3) ||
                SomeBooleanFunction(t1, t3));
    }
    
    uses line breaks and indention to break up long parameter lists and boolean expressions.
  5. Use K&R or Allman style braces: K&R looks like this:
    namespace N {
        class C {
            void f() {
                int x;
            }
        };
    }

    Allman style braces push the opening brace onto its own line:

    namespace N
    {
        class C
        {
            void f()
            {
                int x;
            }
        };
    }
    

    Pick a style of braces and consistently use that style on any given homework or the project.

Comments

  1. Comments go above the code they reference: For the sake of consistency (and to avoid issues with the 80 column limit), place comments above code. (If the comment is super-short, you can get away with placing it off to the side, but don't do it too often.) For example,
    /* This is a well-placed comment. */
    #define AN_IMPORTANT_NUMBER 42
    
    // So is this.
    #define A_SOMEWHAT_IMPORTANT_NUMBER 42
    
    versus other places, e.g.,
    #define AN_IMPORTANT_NUMBER 42      // This is a long comment off to the side
    /* ...or a comment below. */
    
  2. Avoid Useless Comments: Comments that merely repeat the code it references or state the obvious are a travesty to programmers. Comments should state the invariants, the non-obvious, or any references that have more information about the code.
  3. Avoid Over-commenting: Incredibly long comments are not very useful. Long comments should only appear at the top of a file --- here you should explain the overall design of the code and reference any sources that have more information about the algorithms or data structures. All other comments in the file should be as short as possible. After all, brevity is the soul of wit. Most often the best place for any comment is just before a function declaration. You should only need to comment inside the body of a function if it is extremely long or complicated --- variable naming should normally be enough.

Naming

  1. Use meaningful names: Variable names should describe what they are for. Distinguishing what a variable references is best done by following a particular naming convention (see suggestion below). Variable names should be words or combinations of words except in special cases where single letter variables are understood, e.g., i and j for loop variables.
  2. Case and naming conventions: The following table outlines the capitalization conventions we will use for names (in C++):
    Identifier Case Example
    Class Pascal AppDomain
    Method Pascal ToString
    Parameters, Locals, and Fields Lower-case-underscores my_variable
    Namespace Lower-case-underscores std::my_namespace
    Enumeration type Pascal ErrorLevel
    Enumeration values Angry FATAL_ERROR
    Macros Angry MY_AWESOME_MACRO

    Definitions: Pascal case capitalizes the first letter of each word in the name. Lower-case-underscores (LCU) has no capital letters and separates words by underscores. Angry case is all-caps with words separate by underscores.

  3. Don't abuse typedef and using namespace in header files: Only typedef types that would be useful to someone who #includes the header file, because whatever you typedef in a header file carries over to any file that includes it. When it comes to using namespace, you usually shouldn't put this line in the header file for the same reason --- it automatically carries over to any file that #includes it, and could cause some name clashes.

Verbosity

  1. Don't rewrite existing code: The C and C++ standard libraries have a number of functions and data structures --- use them (unless otherwise stated)!
  2. Boolean Zen: Remember that the type of the condition in an if-statement is bool. Avoid redundancy in your condition if you already have a value of type bool. For example
    if (foo == true) { /* ... */ }
    
    is redundant as foo must be a boolean variable. Therefore, we should rewrite this as
    if (foo) { /* ... */ }