Skip to content
Snippets Groups Projects
codingStyleGuide.org 7.06 KiB
Newer Older
#                            -*- mode: org; -*-
#
#+TITLE:                 OpenFOAM C++ style guide
#+AUTHOR:                      OpenCFD Ltd.
#+DATE:                       November 2009
#+LINK:                  http://www.opencfd.co.uk
#+OPTIONS: author:nil ^:{}

* OpenFOAM C++ style guide

*** General
    + 80 character lines max
    + The body of control statements (eg, if, else, while, etc).
      always delineated with brace brackets
Mark Olesen's avatar
Mark Olesen committed
    + Use spaces for indentation, not tab characters.
    + The normal indentation is 4 spaces per logical level.
    + Avoid trailing whitespace.
Mark Olesen's avatar
Mark Olesen committed
      << is always four characters after the start of the stream,
      so that the << symbols align, i.e.
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      Info<< ...
      os  << ...
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      WarningIn("className::functionName()")
          << "Warning message"
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      WarningIn("className::functionName()")
      << "Warning message"
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

    + no unnecessary class section headers, i.e. remove

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

      // Check

      // Edit

      // Write
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

      if they contain nothing, even if planned for 'future use'

    + class titles are centred

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     /*---------------------------------------------------------------------------*\
                             Class exampleClass Declaration
     \*---------------------------------------------------------------------------*/
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     /*---------------------------------------------------------------------------*\
                    Class exampleClass Declaration
     \*---------------------------------------------------------------------------*/
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

*** .H Files
    + header file spacing
      Leave two empty lines between sections (as per functions in the .C file etc)

    + use "//- Comment" comments in header file
      + add descriptions to class data and functions
    + destructor
      If adding a comment to the destructor - use //- and code as a normal function:

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      //- Destructor
      ~className();
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
    + inline functions
      Use inline functions where appropriate in a separate classNameI.H file.
Mark Olesen's avatar
Mark Olesen committed
      Avoid cluttering the header file with function bodies.

*** .C Files
    + Do not open/close namespaces in a .C file
      Fully scope the function name, i.e.

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      Foam::returnType Foam::className::functionName()
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      namespace Foam
      {
          ...

          returnType className::functionName()

          ...
      }
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

      EXCEPTION

      When there are multiple levels of namespace, they may be used in the .C
      file, i.e.

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      namespace Foam
      {
      namespace compressible
      {
      namespace RASModels
      {

          ...

      } // End namespace RASModels
      } // End namespace compressible
      } // End namespace Foam
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

    + Use two empty lines between functions

*** Coding Practise
    + passing data as arguments or return
Mark Olesen's avatar
Mark Olesen committed
      Pass bool, label and scalar as copy, anything larger by reference.
    + const
      Use everywhere it is applicable.
    + variable initialisation using "="

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      const className& variableName = otherClass.data();
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
      const className& variableName(otherClass.data());
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

    + virtual functions
      If a class is virtual - make all derived classes virtual.

*** Conditional Statements
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

    NOT (no space between "if" and "(")

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
    for (i = 0; i < maxI; i++)
    {
        code;
    }
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

    NOT (no space between "for" and "(")

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
    for(i = 0; i < maxI; i++)
    {
        code;
    }
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

*** `forAll' loops
    like for loops, but

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

*** Splitting Over Multiple Lines
   + splitting return type and function name
     + split initially after the function return type and left align

Mark Olesen's avatar
Mark Olesen committed
     + do not put "const" onto its own line - use a split to keep it with the
       function name and arguments.

     so:

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     const Foam::longReturnTypeName&
     Foam::longClassName::longFunctionName const
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     const Foam::longReturnTypeName&
         Foam::longClassName::longFunctionName const
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     const Foam::longReturnTypeName& Foam::longClassName::longFunctionName
     const
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     const Foam::longReturnTypeName& Foam::longClassName::
     longFunctionName const
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE


     + if need to split again, split at the function name (leaving behind the
Mark Olesen's avatar
Mark Olesen committed
         preceding scoping "::"s), and again, left align, i.e.
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
       const Foam::longReturnTypeName&
       Foam::veryveryveryverylongClassName::
       veryveryveryverylongFunctionName const
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

   + splitting long lines at an "="

     Indent after split

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     variableName =
         longClassName.longFunctionName(longArgument);
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     variableName =
         longClassName.longFunctionName
         (
             longArgument1,
             longArgument2
         );
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     variableName =
     longClassName.longFunctionName(longArgument);
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
     variableName = longClassName.longFunctionName
     (
         longArgument1,
         longArgument2
     );
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE

*** Maths and Logic
    + operator spacing
      + a + b, a - b
      + a*b, a/b
      + a & b, a ^ b
      + a = b, a != b
      + a < b, a > b, a >= b, a <= b
      + a || b, a && b

    + splitting formulae over several lines
      Split and indent as per "splitting long lines at an "=""
      with the operator on the lower line.  Align operator so that first
      variable, function or bracket on the next line is 4 spaces indented i.e.

Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
          a * (a + b)
Mark Olesen's avatar
Mark Olesen committed
        * (k + t);
#+END_EXAMPLE

      This is sometime more legible when surrounded by extra parentheses:

#+BEGIN_EXAMPLE
      variableName =
      (
          a * (a + b)
        - exp(c/d)
        * (k + t)
      );
#+END_EXAMPLE

    + splitting logical tests over several lines

Mark Olesen's avatar
Mark Olesen committed
      outdent the operator so that the next variable to test is aligned with
      the four space indentation, i.e.
Mark Olesen's avatar
Mark Olesen committed
#+BEGIN_EXAMPLE
Mark Olesen's avatar
Mark Olesen committed
#+END_EXAMPLE