-
Henry authoreda3d18c64
OpenFOAM C++ style guide
#
OpenFOAM C++ style guide
General
- 80 character lines max
- The normal indentation is 4 spaces per logical level.
- Use spaces for indentation, not tab characters.
- Avoid trailing whitespace.
- The body of control statements (eg,
if
,else
,while
, etc). is always delineated with brace brackets. A possible exception can be made in conjunction withbreak
orcontinue
as part of a control structure. - The body of
case
statements is usually delineated with brace brackets. - A fall-through
case
should be commented as such. - stream output
-
<<
is always four characters after the start of the stream, so that the<<
symbols align, i.e.Info<< ... os << ...
so
WarningIn("className::functionName()") << "Warning message"
not
WarningIn("className::functionName()") << "Warning message"
-
- no unnecessary class section headers, i.e. remove
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Check
// Edit
// Write
if they contain nothing, even if planned for ‘future use’
- class titles are centred
/*---------------------------------------------------------------------------*\
Class exampleClass Declaration
\*---------------------------------------------------------------------------*/
not
/*---------------------------------------------------------------------------*\
Class exampleClass Declaration
\*---------------------------------------------------------------------------*/
The .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 to add descriptions to class data and functions do be included in the Doxygen documentation:- text on the line starting with
//-
becomes the Doxygen brief description; - text on subsequent lines becomes the Doxygen detailed description e.g.
//- A function which returns a thing // This is a detailed description of the function // which processes stuff and returns other stuff // depending on things. thing function(stuff1, stuff2);
- list entries start with
-
or-#
for numbered lists but cannot start on the line immediately below the brief description so//- Compare triFaces // Returns: // - 0: different // - +1: identical // - -1: same face, but different orientation static inline int compare(const triFace&, const triFace&);
or
//- Compare triFaces returning 0, +1 or -1 // // - 0: different // - +1: identical // - -1: same face, but different orientation static inline int compare(const triFace&, const triFace&);
not
//- Compare triFaces returning 0, +1 or -1 // - 0: different // - +1: identical // - -1: same face, but different orientation static inline int compare(const triFace&, const triFace&);
- list can be nested for example
//- Search for \em name // in the following hierarchy: // -# personal settings: // - ~/.OpenFOAM/\<VERSION\>/ // <em>for version-specific files</em> // - ~/.OpenFOAM/ // <em>for version-independent files</em> // -# site-wide settings: // - $WM_PROJECT_INST_DIR/site/\<VERSION\> // <em>for version-specific files</em> // - $WM_PROJECT_INST_DIR/site/ // <em>for version-independent files</em> // -# shipped settings: // - $WM_PROJECT_DIR/etc/ // // \return the full path name or fileName() if the name cannot be found // Optionally abort if the file cannot be found fileName findEtcFile(const fileName&, bool mandatory=false);
- for more details see the Doxygen documentation.
- text on the line starting with
- destructor
- If adding a comment to the destructor -
use
//-
and code as a normal function://- Destructor ~className();
- If adding a comment to the destructor -
use
- inline functions
- Use inline functions where appropriate in a separate classNameI.H file. Avoid cluttering the header file with function bodies.
The .C Files
- Do not open/close namespaces in a .C file
- Fully scope the function name, i.e.
Foam::returnType Foam::className::functionName()
not
namespace Foam { ... returnType className::functionName() ... }
EXCEPTION
When there are multiple levels of namespace, they may be used in the .C file, i.e.
namespace Foam { namespace compressible { namespace RASModels { ... } // End namespace RASModels } // End namespace compressible } // End namespace Foam
- Fully scope the function name, i.e.
- Use two empty lines between functions
Coding Practice
- passing data as arguments or return values.
- Pass bool, label and scalar as copy, anything larger by reference.
- const
- Use everywhere it is applicable.
- variable initialisation using
const className& variableName = otherClass.data();
not
const className& variableName(otherClass.data());
- virtual functions
- If a class is virtual, make all derived classes virtual.
Conditional Statements
if (condition)
{
code;
}
OR
if
(
long condition
)
{
code;
}
not (no space between if
and (
used)
if(condition)
{
code;
}
for
and while
Loops
for (i = 0; i < maxI; i++)
{
code;
}
OR
for
(
i = 0;
i < maxI;
i++
)
{
code;
}
not this (no space between for
and (
used)
for(i = 0; i < maxI; i++)
{
code;
}
Note that when indexing through iterators, it is often slightly more
efficient to use the pre-increment form. Eg, ++iter
instead of iter++
forAll
, forAllIter
, forAllConstIter
, etc. loops
like for
loops, but
forAll(
not
forAll (
Using the forAllIter
and forAllConstIter
macros is generally
advantageous - less typing, easier to find later. However, since
they are macros, they will fail if the iterated object contains
any commas.
The following will FAIL!:
forAllIter(HashTable<labelPair, edge, Hash<edge> >, foo, iter)
These convenience macros are also generally avoided in other container classes and OpenFOAM primitive classes.
Splitting Over Multiple Lines
Splitting return type and function name
- split initially after the function return type and left align
- do not put
const
onto its own line - use a split to keep it with the function name and arguments.const Foam::longReturnTypeName& Foam::longClassName::longFunctionName const
not
const Foam::longReturnTypeName& Foam::longClassName::longFunctionName const
nor
const Foam::longReturnTypeName& Foam::longClassName::longFunctionName const
nor
const Foam::longReturnTypeName& Foam::longClassName:: longFunctionName const
- if it needs to be split again, split at the function name (leaving
behind the preceding scoping =::=s), and again, left align, i.e.
const Foam::longReturnTypeName& Foam::veryveryveryverylongClassName:: veryveryveryverylongFunctionName const
Splitting long lines at an “=”
Indent after split
variableName =
longClassName.longFunctionName(longArgument);
OR (where necessary)
variableName =
longClassName.longFunctionName
(
longArgument1,
longArgument2
);
not
variableName =
longClassName.longFunctionName(longArgument);
nor