C++ Code Formatter

CodeMorph C++

CodeToHtml

Coding Standards

C++ Coding Standards


You can read and download this C++ Coding Standards coding style guide and code guidelines from here for free at your own risk. All registered trademarks, product names and company names or logos mentioned herein are the property of their respective owners.

C++ Coding Standards

Author: Brett Slocum

Date: 02/13/1997

  1. Introduction

    This documentation describes coding standards using C/C++ in our environment. As with most standards and guidelines, this document is not fixed in concrete, but it is not a suggestion either. Programmers are required to follow these recommendatio

    As such, the standards are not intended to create obstacles or encourage bureaucracy. Consequently, if programmers see revisions need to be made, it is their responsibility to review changes with the architect team so they can be incorporated in the s

    If a particular situation arises where a good case can be made to violate the standards, discuss it with the architecture team and fully document the variance.

  2. File Organization

    C++ source files should have a .cpp extension. Each source file should always have a header file with same name and a .h extension.

    File names should be 31 characters or less. No embedded spaces should be used in file names. The name of the file should be the name of the class contained in the file without the leading "C".

    Examples:

    Valid filenames for the given classes:

     Class                  Source File              Header File
    CCPRMoleculeCPRMolecule.cppCPRMolecule.h
    CCCAMyClassCCAMyClass.cppCCAMyClass.h
    CCPRAtomRevisionCPRAtomRevision.cppCPRAtomRevision.h

    There should be only one primary class definition per file.

    1. Header Files
      1. Comment Block

        The comment block in a header file describing the purpose and maintenance history of the file should follow the template below:

            #ifndef CLASSNAME_H
            #define CLASSNAME_H
        
            ///////////////////////////////////////////////////////////////////////////////
            //
            // $Header:  $
            //
            // NAME:  className
            //
            // BASE  CLASSES: none
            //
            // PURPOSE:  purpose description
            //
            // AUTHOR:  Who created this originally
            //
            //  COPYRIGHT NOTICE:
            //
            //      (C) Residential Funding Corporation
            //      Created in 1997 as an unpublished copyright work.  All rights reserved.
            //      This document and the information it contains is confidential and
            //      proprietary to Residential Funding Corporation.  Hence, it may not be
            //      used, copied, reproduced, transmitted, or stored in any form or by any
            //      means, electronic, recording, photocopying, mechanical or otherwise,
            //      without the prior written permission of Residential Funding
            //      Corporation.
            //
            //  REVISION HISTORY:
            // $Log:      $
            ///////////////////////////////////////////////////////////////////////////////
        
            // Includes
        
            // Constants
        
            // Types and Classes
        
            // ... rest of the file goes here
        
            #endif // CLASSNAME_H
        
        

      2. Allowed Contents

Header files may contain:

    1. Type definitions
    2. Templates
    3. Function declarations
    4. Inline function definitions
    5. External data declarations
    6. Constant definitions
    7. Enumeration types
    8. Name declarations
    9. Include statements
    10. Comments

Examples:

Lexical Element

Example of Code

Notes/Comments

Type Definition

    typedef float REAL; 

Define a type REAL which is a floating-point number

Template

    List<Atom> *resatomlist; 

Example of class data using templates

Function Declaration

    Atom *GetAtom( Atom *atom); 

A class member function declaration

Inline Function Definition

    inline char* CResidue::GetResidueName() {return residuename;}

An access function for class Residue

External Data Declaration

    extern CString sName;

 

Constant Definition

const float pi = 3.14159;

The keyword const redefines the word pi to mean a floating-point number whose value is set to 3.14159

Enumeration

    enum EColor(red, green, blue}; EColor eColor;

Thus, we could specify:

    eColor=green;

to set eColor

Name declaration

   

Include statement

    #include "Molecule.h"

The quotes indicate a user-defined header file is to be included.

Comment

    // This is a comment line

The C++ comment characters (//) should be used in preference over the old style (/* and */) comment characters.

They may not contain:

    1. Ordinary function definitions
    2. Variable definitions
    3. Constant aggregate definitions
    4. External references to global variables
      1. Guard Code

        Header files will define and test a preprocessor variable preventing multiple inclusion of that header file in the same translation unit:

            #ifndef RESIDUE_H
            #define RESIDUE_H
        
            ...rest of code...
        
            #endif
        

      2. Include Statements

Each header file will contain #include statements for all header files on which it depends:

    #include "header_file.h"

or

    #include <header_file.h>

for default (compiler-default) header files. Do not include pathnames in the #include statement. Use the Tools/Options menu in Developer Studio to add directories to the search path.

Do not create order dependencies among header files for classes that reference each other. Specify forward declarations for each class to avoid this situation.

Do not group forward references into a single header file. While this has some organization appeal, it results in superfluous class declarations.

    1. Source Files
      1. Comment Block

        The comment block in a source file describing the purpose and maintenance history of the file should follow the template below:

            ///////////////////////////////////////////////////////////////////////////////
            //
            // $Header:  $
            //
            // NAME:  className
            //
            // BASE  CLASSES: none
            //
            // PURPOSE:  purpose description
            //
            // AUTHOR:  Who created this originally
            //
            //  COPYRIGHT NOTICE:
            //
            //      (C) Residential Funding Corporation
            //      Created in 1997 as an unpublished copyright work.  All rights reserved.
            //      This document and the information it contains is confidential and
            //      proprietary to Residential Funding Corporation.  Hence, it may not be
            //      used, copied, reproduced, transmitted, or stored in any form or by any
            //      means, electronic, recording, photocopying, mechanical or otherwise,
            //      without the prior written permission of Residential Funding
            //      Corporation.
            //
            //  REVISION HISTORY:
            // $Log:      $
            //
            ///////////////////////////////////////////////////////////////////////////////
        
            ///////////////////////////////////////////////////////////////////////////////
            //  Includes
        
            // Constants
        
            // Externals
        
            // Types and Classes
        
            // Variables
        
            // Member Functions
        

      2. Include Statements

        Only those header files needed directly by the source file should be included.

        For Visual C++, StdAfx.h should be included first for the proper creation of precompiled headers. No other code, except for comments can precede the StdAfx.h include.

      3. Function Comments

Each function (excluding Get and Set access functions and Operators) must have a header that includes the following elements:

NAME
Name of the function
DESCRIPTION
Describes the purpose, usage and other important information concerning this function. Any precondition should be specified here. Note: Do not describe how the function does its job. That's what the source code is for. One doesn't wa
PARAMETERS
A list of each of the parameter names and a brief description of that parameter. The name of the parameter should be followed by one of three
RETURN
The type returned and a brief description of that object. Include any requirement for this return type (e.g. must release the memory).
SIDE EFFECTS
Anything that might happen that would not normally be expected by a user.

Example:

    ///////////////////////////////////////////////////////////////////////////////
    //
    // NAME:  open
    //
    // DESCRIPTION:  opens the specific file.
    //
    // PARAMETERS:  path(0)  - full pathname for the file to be opened
    //
    // RETURN:  CStatus    - Boolean, indicates success or failure
    //
    // SIDE  EFFECTS: none
    //
    ///////////////////////////////////////////////////////////////////////////////

    BOOL CStatus open(char *path)
    {
         function body….
    }

  • Source Code Style
    1. Naming Conventions

      Do not rely on upper and lower case differences to yield unique names.

      1. Word separators

        Separate words in identifiers by capitals, not underscores.

      2. Prefixes

        Variable names should be prefixed by Hungarian notation. More than one prefix may apply (e.g. a pointer to an exception object could be named pxPricingException). Regular prefixes include:

        Prefix

        Data Type

        a

        array

        b

        BOOL

        by

        unsigned char (BYTE or UCHAR)

        c

        char

        C

        class

        d

        double

        dw

        DWORD (unsigned long)

        e

        enum variable

        E

        enumerated type

        f

        float

        h

        Windows handle

        i

        int or short

        l

        long

        m_

        class member variable

        n

        int

        p

        pointer

        s

        CString

        sz

        zero-terminated char string

        u

        unsigned int

        v

        void

        w

        WORD (unsigned word)

        x

        C++ exception object

      3. Names

      Names of enumerated types and classes should begin with an uppercase letter (either E or C, respectively), whereas names of variables and constants should begin with a lowercase letter. Use the Windows standard of starting functions with an upperca

      Names should indicate the meaning of the variables, rather than their type. Names should be descriptive and use complete words. Avoid the use of initial or trailing underscores. Use multiple words – but use them carefully. It can be hard to remember

      Similarly:

      Correct Incorrect
      szDateDue szDueDate
      szNameFirst szFirstName
      eColorRed eRedColor
      iVolumeMax iMaxVolume
      bStatusEnabled bEnabledStatus

      Naming variables this way means that related variables tend to sort together, making cross-reference listings more useful.

    2. Aesthetics
      1. Indent size

        Use four spaces. Do not use tabs because different editors and printers deal with tabs differently. These parameters can be set in the Tools/Options menu of Visual C++.

      2. Braces

        Braces shall follow an indented block style in which opening and closing braces are each placed on separate line lined up vertically with the control statement. The body of the code within braces is indented by one indent level.

        Example:

            while (iLoopingCount)
            {
                doSomeThing();
            }
        

      3. Line length

        Line length should not exceed eighty characters.

      4. Statements

        Do not use multiple statements per line.

        Example:

            // Incorrect
        
            a = b; c++; d = GetMax();
        
            // Correct
        
            a = b;
            c++;
            d = GetMax();
        

      5. Class definitions

        Put class names against the margin.

        Example:

            WORD
            class::func()
            {
                doSomeThing();
            }
        

      6. Spaces

      Use lots of spaces, except around ‘.' or ‘->' or between unary operators and operands.

      Pointer modifiers "*" and reference modifiers "&" in declarations are grouped with the type, not the variable. Overloaded operators immediately follow the key word operator, with no intervening white space.

      Example:

          char* p = "hello";
      
          Complex operator+ (const Complex& op1, const Complex& op2);
      

    3. Comments

      Comments should be used liberally to explain what code is doing and why, but should not duplicate information readily discernable in the code itself. Comments are meant to be read by others, so liberal use of white space and blank lines will incre

      Use C++-style comments (i.e. // ), except where commenting out part of the middle of a line (such as unused formal parameters). There should be one space between the double slash and the start of the comment text.

      Example:

          Unsigned draw_rect(unsigned wWidth, unsigned wHeight /*, unsigned wDepth */)
      

      1. Block Comments

        Block comments should have blank lines above and below. A block comment is a comment containing two or more lines.

        Examples:

            // This is a C++ block comment.
            // It has two lines in it.
        
            // This is a single-line comment
        

      2. End of Line Comments

      End of line comments are small annotation tacked on the end of a line of code. They are focused on one or a very line of codes where block comments refer to larger sections of code.

      Example:

          IEmployeeCur = iEmployeeCur + 1;       // Keep the index pointer
                                                 // synchronized for OLE clients
      

    4. Constants

      Do not use #define to declare constant values. Const or enum should be used instead.

      Example:

          const WORD wMode;
      

      Use enumeration for a set of related constants rather than declaring them separately.

      Example:

          // Incorrect
          const unsigned int iCOLOR_RED = 0;
          const unsigned int iCOLOR_GREEN = 1;
          const unsigned int iCOLOR_BLUE = 2;
      
          // Correct
          enum EColor {eRed, eGreen, eBlue};
      

      Do not repeat const declarations in both source and header files. If it is declared in the header file, it is meant for other modules to share. If it is declared in the source file, only that module is meant to use it.

      Use constant variables, instead of literal constants, especially if used in more than one place.

      Example:

          // Incorrect
          int iID = 1000;
      

          // Correct

      In the .CPP file:

          int iID = iStartingID;
      

      In the .h file:

          const int iStartingID =        1000;
      

    5. Variables

      Limit the scope of variables as much as possible.

      Each variable is to be declared in a separate declaration statement.

      Examples:

          // Incorrect
          CString sFilename, &rsDirectory;
      
          // Correct
          CString sFilename;
          CString& rsDirectory;
      

      Define variables close to where they will be used.

      Always initialize variables. Declare and initialize variables no earlier than the point at which their initialization values are known.

      Avoid local variable names that are identical to the names of variables with greater scope.

      Beware of the variable's scope. The variable will often remain in existence longer than originally anticipated.

      1. Global variable definitions

      Global variables are strongly discouraged.

      Do not use global variables that only have module (throughout the current source file only) scope.

    6. Classes

      Use struct when there are no private or protected member data and no member functions (including constructors and destructors). In other words, use struct for public data structures. Use class in all other cases.

      Member data and functions should be declared in the following order: public members, protected members, and private members. Always use the access keywords public, protected, and private.

      1. Encapsulation

        Member data in a class should be declared private, not protected or public. This is to adhere to the object-oriented design principle of data encapsulation. If other classes need access to member data, provide get and

        Hide member functions that are not required for the external interface using the private or protected keyword.

        Localize and hide design decisions that may change.

      2. Inheritance

        When using inheritance, specify public for each parent class.

        Example:

        class myClass
        {
            // ….
        }
        
        class derivedClass : public myClass
        {
            // ….
        }
        
        

        In Visual C++, classes that have no other parent class should be derived from CObject. This allows these classes to be part of templated collection classes.

        Avoid multiple inheritance.

      3. Member Functions

        Keep function length to less than two pages. One page is better. Long functions are more difficult to understand and maintain.

        Do not use variable length argument lists (similar to printf).

        Large function parameters should be passed by reference, not by value. If the function is not changing the value of a large parameter, declare that parameter const. Small parameters that won't be changed by the function can be passed by value.

        Whenever an address is returned from a member function, it should be returned as a const pointer or a const reference, unless you want the user to be able to change the contents of what the pointer de-references.

        1. Inline Functions

          Inline functions should not be used, unless performance is known to be a problem. The exception to this rule is access functions, which should be inline, but not within the body of the class.

          Constructors and destructors should not be inline.

          Inline functions should be three lines long or less.

          Example:

              // Incorrect
          
              class CPriority
              {
                  public:
                      int        CPriority() // should not use inline here
                      {
                          doSomething();
                      };
                 int getx();
                 private:
                     int   x;
              };
          
              int CPriority::getx() // inline should be used here
              {
                  return(x);
              }
          
              // correct
          
              class CPriority
              {
                   public:
                      int        CPriority(); // constructor should not use inline
                      int getx();
          
                   private:
                       int   x;
              };
          
              // constructor
              int CPriority::CPriority()
              {
                  doSomeThing();
              }
          

              inline int CPriority::getx () // get function can use inline
              {
                  return(x);
              }
          

        2. const Member Functions

        A member function that does not affect the state of an object (its member data) is to be declared const. Member functions declared as const may not modify member data and are the only functions that may be invoked on const obj

      4. Constructors and Destructors

        Initialize member data in the class constructor. Pointers should be set to 0 in the constructor and deleted in the destructor.

        Constructors should use initialization, not assignment, to set member data, if possible.

        Example:

            // Incorrect
        
            Catom::Catom(int iAtNum, float fAtWt)
            {
                m_iAtomicNumber = iAtNum;
                m_fAtomicWeight = fAtWt;
            }
        
            // Correct
        
            Catom::Catom(int iAtNum, float fAtWt) : m_iAtomicNumber(iAtNum),
             m_fAtomicWeight(fAtWt)
            {
                ;    // Empty
            }
        

        A class that uses the new keyword to allocate objects managed by the class must define a copy constructor. This is to avoid surprises when an object is initialized using an object of the same type. If an object manages the allocation an

        Example:

            //  Incorrect
        
            class String
            {
                public:
                    String( const char* cp = "");    // constructor
                    ~String();                       // destructor
                private:
                     char *sp;
            };
        
            String::String(const char* cp) : sp ( new char[strlen(cp)] )     // constructor
            {
                strcpy(sp, cp);
            }
        
            String::~String()                            // destructor
            {
                delete sp;
            }
        
            void
            main()
            {
                String w1;
                String w2 = w1;
        
                // Warning:  the destructor for w1::sp will be called twice:
                // first when w1 is destroyed;  again, when w2 is destroyed.
            }
        
            //  Correct
        
            class String
            {
                public:
                    String( const char* cp = "" );    // constructor
                    String( const String& sp );       // copy constructor
                    ~String();                        // destructor
                    // …
                 private:
                     char *sp;
                     // …
            };
        
            String::String( const String& stringA ) : sp( new char[strlen(stringA.sp)] )
            {
                strcpy ( sp, stringA.sp );
            }
        
            String::~String()                            // destructor
            {
                delete sp;
            }
        
            void
            main()
            {
                String w1;
                String w2 = w1;     // SAFE COPY:   String::String( const String& ) called.
            }
        

        All classes that are used as base classes and have virtual functions, must define a virtual destructor.

        Avoid the use of global objects in constructors and destructors.

      5. Operator Overloading

        Use operator overloading sparingly and in a uniform manner. One disadvantage in overloading operators is that it is easy to misunderstand the meaning of an overloaded operator

      6. Friends

      Use friend functions sparingly. Friends offer an orderly way of getting around data encapsulation for a class. A friend class can be advantageously used to provide functions that require data that is not normally needed by the class

    7. Flow Control Structures

      A break statement must always terminate the code following a case label.

      A switch statement must always contain a default branch that handles unexpected cases.

      If testing the value of a single variable, use a switch statement instead of an if statement.

      The flow control statements if, while, for and do should be followed by a block, even if it is empty or contains a single line.

      Example:

          //Incorrect
      
          while ( !bSomething ) ;
          for ( i = 0; i < 10; i++ )
              cout << aSomeArray[I];
      
          //Correct
      
          while ( !bSomething )
          {
              ;    // Empty
          }
      
          for ( i = 0; i < 10; i++ )
          {
              cout << aSomeArray[I];
          }
      

      Do not embed assignment statements into flow control statements.

      Example:

          // Incorrect
      
          if ( bFlag = GetStatusWrite() )
          {
              ...
          }
      
          // Correct
      
          bFlag = GetStatusWrite();
          if ( bFlag )
          {
              ...
          }
      

      Never use goto. Goto breaks the control flow and can lead to code that is difficult to comprehend.

      Avoid the use of continue. Continue can be used to exit from loops. However, code may be more comprehensible by using an else clause instead.

      1. Boolean Tests

        Only use if (something) and if (!something) when something is a BOOL value. If it is a multi-valued variable or a pointer, test for equality with 0.

        Examples:

            if (!strcmp( myString, "value" )) // Bad
            if (strcmp( myString, "value" ) == 0)  // Good
        

      2. Control Statement Overrides

      Minimize the use of return, break, continue and goto statements which override normal control statement structure. However, each of these statements has a place - use them when the code would be significantly more convo

    8. Additional Guidelines
      1. Debugging

        Test the input parameters of a member function for valid data using the assert function.

      2. Exceptions

        Catch exceptions thrown by MFC functions. Use a try-catch block around calls to these functions.

        Example:

            CRecordSet clPriceData;
        
            try
            {
                clPriceData.Open();
            }
            catch (CDBException* pxOpen)
            {
                pxOpen.
            }
        

      3. Unions

        Avoid unions, as they defeat strong type-checking and are very difficult to verify in a debugger.

      4. Use C++ memory management

        Do not use realloc. Malloc, calloc, and free should be avoided; the operators new and delete should be used instead.

        Always use delete whenever memory was allocated by the new operator. In order to help eliminate the problem of accessing memory that has been freed, the pointer must be assigned to 0 after the pointer has been deleted. Note: there are in

      5. Input / Output

        Use the C++-style iostream class, not printf, fprintf, or other C-style input/output routines.

      6. MFC

        Use the BOOL and CString classes provided by MFC, not int (for boolean responses) or char* types from C.

        Use MFC classes where appropriate.

      7. Null Pointer

    The C++ language definition unequivocally defines a pointer value of 0 (zero), or any expression that evaluates to zero, as a null pointer. Stroustrup writes, "A constant expression that evaluates to zero is converted to a pointer, commonly c

  • References

    1. C++ Coding Standard, Apertus Enterprise Systems Group, January 1997.
    2. C/C++ Programming Guide, Hassan Kaganda, Deluxe Corporation, January 1997.
    3. Programming in C++, Rules and Recommendations, Mats Henricson and Erik Nyquist, Ellemtel Telecommunications Systems Laboratories, April 1992.
    1. Glossary

      abstract base class

      A class from which no objects may be created; it is only used as a base class for the derivation of other classes. A class is abstract if it includes at least one pure virtual member function.

      access function

      A function that set or returns the value of member data.

      accessor

      See access function.

      catch clause

      The exception handler executed when an exception is raised. The definition of an exception handler begins with the keyword catch.

      class

      A user-defined data type that consists of data elements and functions that operate on that data. In C++, this may be declared as a class; it may also be declared as a struct or a union.

      class template

      Definition of a family of classes. A new class may be created from a class template by providing values for a number of arguments. These values may be names of types or constant expressions.

      compilation unit

      The source code (after preprocessing) that is submitted to a compiler for compilation.

      constant member function

      A function that may not modify member data.

      constructor

      A function that initializes an object when it is created.

      copy constructor

      A constructor in which the first argument is a reference to an object that has the same type as the object to be initialized. A copy constructor is used to initialize an object to the same value as another object of the same type.

      default constructor

      A constructor that needs no arguments. The compiler often automatically generates a default constructor for a class, if the programmer does not define one.

      destructor

      A function called when an object is destroyed.

      enumeration type

      An explicitly declared set of symbolic integer constants. In C++ it is declared as an enum.

      exception

      A run-time program anomaly that is detected in a function or member function. Exception handling provides for the uniform management of exceptions. When an exception is detected, it is thrown (using a throw expression) to the exception handler.

      forwarding function

      A function that does nothing more than call another function.

      function template

      Definition of a family of functions. A new function may be created from a function template by providing values for a number of arguments. These values may be names of types or constant expressions.

      identifier

      A name that is used to refer to a variable, constant, function or type in C++. When necessary, an identifier may have an internal structure that consists of a prefix, a name, and a suffix (in that order).

      inline function

      A function declared with the inline keyword that gets directly replaced by its statements at compile time. Also, any member functions declared within the body of a class are automatically inline.

      iterator

      An object which, when invoked, returns the next object from a collection of objects.

      macro

      A name for a text string which is defined in a #define statement. When this name appears in source code, the compiler replaces it with the defined text string.

      member data

      Data identifiers defined within a class.

      member function

      Functions defined within a class.

      overloaded function

      A function name that is used for two or more functions or member functions having different types.

      overridden member function

      A member function in a base class that is redefined in a derived class. Such a member function is declared virtual.

      predefined data type

      A type defined in the C++ language, such as int or float.

      private member

      The member data and member functions of a class that are only accessible within the class.

      protected member

      The member data and member functions of a class that are only accessible within the class and its derived classes.

      public member

      The member data and member functions of a class that are accessible everywhere.

      pure virtual function

      A member function for which no definition is provided. Pure virtual functions are specified in abstract base classes and must be defined (overridden) in derived classes.

      reference

      An identifier that refers to another identifer directly. In C++, the ambersand (&) is used immediately after the data type to indicate that the declared variable, constant, or function argument is a reference.

      scope The context of a program in which an identifier exists.

      structure

      A user-defined type for which only public data is specified.

      typedef

      A typedef declaration in C++ specifies another name for a data type.

      user-defined data type

      A type that is defined by a programmer in a class, struct, union, enum, or typedef definition or as an instantiation of a class template.

      Want to format C++ source code automatically?  Use SourceFormatX C++ Code Formatter to indent your C++ code files.