3 #+TITLE: OpenFOAM C++ style guide
4 #+AUTHOR: OpenFOAM Foundation
6 #+LINK: http://www.OpenFOAM.org
7 #+OPTIONS: author:nil ^:{}
11 * OpenFOAM C++ style guide
13 + 80 character lines max
14 + The normal indentation is 4 spaces per logical level.
15 + Use spaces for indentation, not tab characters.
16 + Avoid trailing whitespace.
17 + The body of control statements (eg, =if=, =else=, =while=, etc). is
18 always delineated with brace brackets. A possible exception can be
19 made in conjunction with =break= or =continue= as part of a control
21 + The body of =case= statements is usually delineated with brace brackets.
22 + A fall-through =case= should be commented as such.
25 + =<<= is always four characters after the start of the stream,
26 so that the =<<= symbols align, i.e.
33 WarningIn("className::functionName()")
38 WarningIn("className::functionName()")
42 + no unnecessary class section headers, i.e. remove
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 if they contain nothing, even if planned for 'future use'
54 + class titles are centred
56 /*---------------------------------------------------------------------------*\
57 Class exampleClass Declaration
58 \*---------------------------------------------------------------------------*/
64 /*---------------------------------------------------------------------------*\
65 Class exampleClass Declaration
66 \*---------------------------------------------------------------------------*/
71 + Leave two empty lines between sections
72 (as per functions in the /.C/ file etc)
73 + use =//- Comment= comments in header file to add descriptions to class
74 data and functions do be included in the Doxygen documentation:
75 + text on the line starting with =//-= becomes the Doxygen brief
77 + text on subsequent lines becomes the Doxygen detailed description /e.g./
79 //- A function which returns a thing
80 // This is a detailed description of the function
81 // which processes stuff and returns other stuff
82 // depending on things.
83 thing function(stuff1, stuff2);
85 + list entries start with =-= or =-#= for numbered lists but cannot start
86 on the line immediately below the brief description so
92 // - -1: same face, but different orientation
93 static inline int compare(const triFace&, const triFace&);
97 //- Compare triFaces returning 0, +1 or -1
101 // - -1: same face, but different orientation
102 static inline int compare(const triFace&, const triFace&);
106 //- Compare triFaces returning 0, +1 or -1
109 // - -1: same face, but different orientation
110 static inline int compare(const triFace&, const triFace&);
112 + list can be nested for example
114 //- Search for \em name
115 // in the following hierarchy:
116 // -# personal settings:
117 // - ~/.OpenFOAM/\<VERSION\>/
118 // <em>for version-specific files</em>
120 // <em>for version-independent files</em>
121 // -# site-wide settings:
122 // - $WM_PROJECT_INST_DIR/site/\<VERSION\>
123 // <em>for version-specific files</em>
124 // - $WM_PROJECT_INST_DIR/site/
125 // <em>for version-independent files</em>
126 // -# shipped settings:
127 // - $WM_PROJECT_DIR/etc/
129 // \return the full path name or fileName() if the name cannot be found
130 // Optionally abort if the file cannot be found
131 fileName findEtcFile(const fileName&, bool mandatory=false);
133 + for more details see the Doxygen documentation.
135 + If adding a comment to the destructor -
136 use =//-= and code as a normal function:
142 + Use inline functions where appropriate in a separate /classNameI.H/
143 file. Avoid cluttering the header file with function bodies.
146 + Do not open/close namespaces in a /.C/ file
147 + Fully scope the function name, i.e.
149 Foam::returnType Foam::className::functionName()
156 returnType className::functionName()
162 When there are multiple levels of namespace, they may be used in the
167 namespace compressible
172 } // End namespace RASModels
173 } // End namespace compressible
174 } // End namespace Foam
177 + Use two empty lines between functions
180 + passing data as arguments or return values.
181 + Pass bool, label and scalar as copy, anything larger by reference.
183 + Use everywhere it is applicable.
184 + variable initialisation using
186 const className& variableName = otherClass.data();
190 const className& variableName(otherClass.data());
193 + If a class is virtual, make all derived classes virtual.
195 *** Conditional Statements
212 *not* (no space between =if= and =(= used)
220 *** =for= and =while= Loops
222 for (i = 0; i < maxI; i++)
239 *not* this (no space between =for= and =(= used)
241 for(i = 0; i < maxI; i++)
246 Note that when indexing through iterators, it is often slightly more
247 efficient to use the pre-increment form. Eg, =++iter= instead of =iter++=
249 *** =forAll=, =forAllIter=, =forAllConstIter=, etc. loops
250 like =for= loops, but
258 Using the =forAllIter= and =forAllConstIter= macros is generally
259 advantageous - less typing, easier to find later. However, since
260 they are macros, they will fail if the iterated object contains
263 The following will FAIL!:
266 forAllIter(HashTable<labelPair, edge, Hash<edge> >, foo, iter)
268 These convenience macros are also generally avoided in other
269 container classes and OpenFOAM primitive classes.
271 *** Splitting Over Multiple Lines
272 ***** Splitting return type and function name
273 + split initially after the function return type and left align
274 + do not put =const= onto its own line - use a split to keep it with
275 the function name and arguments.
277 const Foam::longReturnTypeName&
278 Foam::longClassName::longFunctionName const
282 const Foam::longReturnTypeName&
283 Foam::longClassName::longFunctionName const
287 const Foam::longReturnTypeName& Foam::longClassName::longFunctionName
292 const Foam::longReturnTypeName& Foam::longClassName::
293 longFunctionName const
295 + if it needs to be split again, split at the function name (leaving
296 behind the preceding scoping =::=s), and again, left align, i.e.
298 const Foam::longReturnTypeName&
299 Foam::veryveryveryverylongClassName::
300 veryveryveryverylongFunctionName const
303 ***** Splitting long lines at an "="
307 longClassName.longFunctionName(longArgument);
312 longClassName.longFunctionName
321 longClassName.longFunctionName(longArgument);
325 variableName = longClassName.longFunctionName
339 a < b, a > b, a >= b, a <= b
343 + splitting formulae over several lines
345 Split and indent as per "splitting long lines at an ="
346 with the operator on the lower line. Align operator so that first
347 variable, function or bracket on the next line is 4 spaces indented i.e.
354 This is sometimes more legible when surrounded by extra parentheses:
365 + splitting logical tests over several lines
367 outdent the operator so that the next variable to test is aligned with
368 the four space indentation, i.e.
379 + For readability in the comment blocks, certain tags are used that are
380 translated by pre-filtering the file before sending it to Doxygen.
382 + The tags start in column 1, the contents follow on the next lines and
383 indented by 4 spaces. The filter removes the leading 4 spaces from the
384 following lines until the next tag that starts in column 1.
386 + The 'Class' and 'Description' tags are the most important ones.
388 + The first paragraph following the 'Description' will be used for the
389 brief description, the remaining paragraphs become the detailed
398 A class for specifying the documentation style.
400 The class is implemented as a set of recommendations that may
404 + The class name must be qualified by its namespace, otherwise Doxygen
405 will think you are documenting some other class.
407 + If you don't have anything to say about the class (at the moment), use
408 the namespace-qualified class name for the description. This aids with
409 finding these under-documented classes later.
412 Foam::myUnderDocumentedClass
415 Foam::myUnderDocumentedClass
418 + Use 'Class' and 'Namespace' tags in the header files.
419 The Description block then applies to documenting the class.
421 + Use 'InClass' and 'InNamespace' in the source files.
422 The Description block then applies to documenting the file itself.
428 Implements the read and writing of files.
431 *** Doxygen Special Commands
432 Doxygen has a large number of special commands with a =\= prefix.
434 Since the filtering removes the leading spaces within the blocks, the
435 Doxygen commmands can be inserted within the block without problems.
441 Implements the read and writing of files.
443 An example input file:
453 Within the implementation, a loop over all patches is done:
455 forAll(patches, patchI)
457 ... // some operation
462 *** HTML Special Commands
463 Since Doxygen also handles HTML tags to a certain extent, the angle
464 brackets need quoting in the documentation blocks. Non-HTML tags cause
465 Doxygen to complain, but seem to work anyhow.
468 + The template with type =<HR>= is a bad example.
469 + The template with type =\<HR\>= is a better example.
470 + The template with type =<Type>= causes Doxygen to complain about an
471 unknown html type, but it seems to work okay anyhow.
473 *** Documenting Namespaces
474 + If namespaces are explictly declared with the =Namespace()= macro,
475 they should be documented there.
477 + If the namespaces is used to hold sub-models, the namespace can be
478 documented in the same file as the class with the model selector.
481 documented namespace 'Foam::functionEntries' within the
482 class 'Foam::functionEntry'
485 + If nothing else helps, find some sensible header.
488 namespace 'Foam' is documented in the foamVersion.H file
491 *** Documenting typedefs and classes defined via macros
492 ... not yet properly resolved
494 *** Documenting Applications
495 Any number of classes might be defined by a particular application, but
496 these classes will not, however, be available to other parts of
497 OpenFOAM. At the moment, the sole purpuse for running Doxygen on the
498 applications is to extract program usage information for the '-doc'
501 The documentation for a particular application is normally contained
502 within the first comment block in a /.C/ source file. The solution is this
503 to invoke a special filter for the "/applications/{solver,utilities}/"
504 directories that only allows the initial comment block for the /.C/ files
507 The layout of the application documentation has not yet been finalized,
508 but foamToVTK shows an initial attempt.
511 Given the origins of OpenFOAM, the British spellings (eg, neighbour and not
512 neighbor) are generally favoured.
514 Both '-ize' and the '-ise' variant are found in the code comments. If
515 used as a variable or class method name, it is probably better to use
516 '-ize', which is considered the main form by the Oxford University
522 The word "its" (possesive) vs. "it's" (colloquial for "it is" or "it has")
523 seems to confuse non-native (and some native) English speakers.
524 It is better to donate the extra keystrokes and write "it is" or "it has".
525 Any remaining "it's" are likely an incorrect spelling of "its".