C++ Programming Style Guidelines

Introduction

This document contains guidelines for writing C++ code. The purpose of this guide is to enhance readability and maintainability of source code through the consistent use of Class, method and object naming, and appropriate formatting. Discussions of building software systems and statistical studies of stylistic elements can be found in Code Complete by Steve McConnell (Microsoft Press). Other good resources are listed at the bottom of the page.

It's important to note that these are guidelines, not hard and fast laws. It's suitable to break a guideline anytime it improves the overall readability or maintenance of the code.

Formatting

The objective of formatting is to make code easy to read and interpret. Below is a list of rules that should be followed to achieve that objective:

  • Each line should contain a single statement, and each statement should do exactly one thing.

    Do:

    Don't:

    if (objA.isValid()) { validObjects++; cout << "Valid Object found"; } i++; a[i]=i;

    if (objA.isValid()) { validObjects++; cout << "Valid Object found"; } a[i]=i++;

  • Use a four spaces to indent code that is in a common block (TAB could be used, but had inconsistent representation across different platforms). Use braces to indicate code blocks with the brace on a new line after the control expression with the same indentation level as the control.

    Do:

    Don't:

    if (objA.isValid()) { validObjects++; if (DEBUG) { cout << "Object A is valid"; } }

    if (objA.isValid()) { validObjects++; if (DEBUG){ cout << "Object A is valid"; } }

    if (objA.isValid()) validObject++;

  • Use whitespace to separate elements and operators in line. For multi-line expressions with parenthesis, align the parenthesis segments horizontally. In general, use alignment whenever it enhances readability.

    Do:

    Don't:

    if ((objA.isValid()) && (objA.refCount() >= 12) ) { tally = tally * (objA.refCount() + 1); }

    if((objA.isValid())&&(objA.refCount()>=12)) { tally=tally*(objA.refCount()+1); }

  • Use parenthesis to form explicit groups, and clarify the order of evaluation within an expression.

    Do:

    Don't

    a = ( a * (b + 1) / ((c - d) + (e * f)) ) + g; if ((objA.isValid()) && ((objB.isValid()) || (objC.disabled()))) { tally++; } if (((new_shape.x > left_boundary) && (new_shape.x < right_boundary)) && ((new_shape.y > top_boundary) && (new_shape.y < bottom_boundary))) { inbounds++; }

    a = a*b+1/c-d+e*f+g; if (objA.isValid()&&objB.isValid()||objC.disabled())

  • File content should be within 80 characters. This limit prevents deep nesting of code and makes sure that multiple windows can be opened without scrolling horizontally in the source code.

C++ Specific Formatting

The class definitions of C++ have their own formatting requirements. In general, the PUBLIC declarations should come first, since that is what will be most useful to those who are looking to use the code without modification. Next should be the protected declarations, since those would be useful for those that intend to extend the class functionality through inheritance. Last should be the private declarations because they are of no concern to anyone but the person who might be modifying the class directly.

Example of a good class definition:

class MyClass : public ParentClass { public: MyClass(); MyClass(int x); ~MyClass(); int getX(); private: int m_x; }

Naming Conventions

Setting a naming convention for classes, methods and variables is just as important as following formatting guidelines. Everybody seems to do this differently, but many sources emphasize having some convention which fulfills the following requirements:

  • Makes the scope of the variable obvious.
  • Identifies named constants
  • Formats names to enhance readability
  • Separates Classes, Methods, Types and variables from each other.

The first requirement is often addressed with prefixes. A list of the common prefixes is found below:

Prefix Meaning Examples
g Global variable g_socketList, g_errorLogFile
m Member variable m_xPosition,m_refCount
s Static variable ms_objectCount, ms_deadObjectsStatus
No prefix means it's a local variable i,j,tally,tmp

To identify named constants, the standard convention is to use all caps, with underscores to separate words in the name. Example: GL_DEBUG_TEST, SDL_MOUSE_DOWN.

To format names to make them more readable, there are a number of different ways to do it. To keep prefixes separate from the variable names, the recommended method is to have the first letter from each word in the name to be caps, with the prefix separated from the variable name with an underscore. For variables, the first letter of the actual name should be lowercase. Examples: ms_objectCount, g_errorLogFile, localTally. Methods use the same convention, but without the prefixes.

For classes, types and interfaces, the names follow the same convention as methods, except that the first letter of the name should also be capitalized. Examples: Application, PongUnitTest, MemoryManagerObject, NutritionalInformation.

Abbreviations and acronyms should not be in uppercase except for the first letter where appropriate. Examples of classes: HtmlSourceContainer, DvdRead. Examples of variables and methods: htmlSource, getDvdWriteHandle(), m_processedHtmlSource.

Comments

Choosing how much to comment the code is often difficult to decide. The following guidelines are drawn from several sources:

  • For C++, use // to indicate comments. For plain C code, use /* .. */.
  • Avoid end-of-line comments except for variable declarations and marking #if/#endif lines.
  • Most comments should be on a separate line, at the same indentation level of the code it is commenting.
  • Use comments to document intent. Don't explain how, explain why.
  • Use a block comment (see below) at the top of each file to provide information on what the code in the file does, and a copyright statement.

For bold comments which require a little emphasis, the recommended format is:

// ************************************************************** // This is a bold comment, which might be used to indicate an important section // of code, or just to catch the programmers eye. The bold comment should be // rather rare, otherwise it looses its effectiveness. // **************************************************************

Misc. Guidelines

Below is a list of guidelines which don't really fit into any other sections cleanly, but are worth mentioning.

  • Class variables should never be public. Use private variables and access functions instead (encapsulation).
  • Use of magic numbers in code should be avoided. Numbers other than 0 and 1 should be declared constants instead.
  • Each class declaration should be in its own header (.h) file. Each class should be in its own .cpp file. Exceptions to this rule are when two classes (or templates) are so tightly coupled that they would not be used separately.

Useful Links and References