3 #+TITLE: OpenFOAM C++ style guide
6 #+LINK: http://www.opencfd.co.uk
7 #+OPTIONS: author:nil ^:{}
9 * OpenFOAM C++ style guide
12 + 80 character lines max
13 + The normal indentation is 4 spaces per logical level.
14 + Use spaces for indentation, not tab characters.
15 + Avoid trailing whitespace.
16 + The body of control statements (eg, =if=, =else=, =while=, etc). is
17 always delineated with brace brackets. A possible exception can be
18 made in conjunction with =break= or =continue= as part of a control
20 + The body of =case= statements is usually delineated with brace brackets.
21 + A fall-through =case= should be commented as such.
24 + =<<= is always four characters after the start of the stream,
25 so that the =<<= symbols align, i.e.
35 WarningIn("className::functionName()")
42 WarningIn("className::functionName()")
47 + no unnecessary class section headers, i.e. remove
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
60 if they contain nothing, even if planned for 'future use'
62 + class titles are centred
65 /*---------------------------------------------------------------------------*\
66 Class exampleClass Declaration
67 \*---------------------------------------------------------------------------*/
73 /*---------------------------------------------------------------------------*\
74 Class exampleClass Declaration
75 \*---------------------------------------------------------------------------*/
80 + Leave two empty lines between sections
81 (as per functions in the /.C/ file etc)
83 + use =//- Comment= comments in header file
84 + add descriptions to class data and functions
86 + If adding a comment to the destructor -
87 use =//-= and code as a normal function:
95 + Use inline functions where appropriate in a separate /classNameI.H/ file.
96 Avoid cluttering the header file with function bodies.
99 + Do not open/close namespaces in a /.C/ file
100 + Fully scope the function name, i.e.
103 Foam::returnType Foam::className::functionName()
112 returnType className::functionName()
119 When there are multiple levels of namespace, they may be used in the /.C/
125 namespace compressible
130 } // End namespace RASModels
131 } // End namespace compressible
132 } // End namespace Foam
135 + Use two empty lines between functions
138 + passing data as arguments or return values.
139 + Pass bool, label and scalar as copy, anything larger by reference.
142 + Use everywhere it is applicable.
144 + variable initialisation using
146 const className& variableName = otherClass.data();
152 const className& variableName(otherClass.data());
156 + If a class is virtual, make all derived classes virtual.
158 *** Conditional Statements
178 NOT (no space between =if= and =(= used)
187 *** =for= and =while= Loops
190 for (i = 0; i < maxI; i++)
210 NOT this (no space between =for= and =(= used)
213 for(i = 0; i < maxI; i++)
219 Note that when indexing through iterators, it is often slightly more
220 efficient to use the pre-increment form. Eg, =++iter= instead of =iter++=
222 *** =forAll=, =forAllIter=, =forAllConstIter=, etc. loops
223 like =for= loops, but
235 Using the =forAllIter= and =forAllConstIter= macros is generally
236 advantageous - less typing, easier to find later. However, since
237 they are macros, they will fail if the iterated object contains
240 The following will FAIL!:
243 forAllIter(HashTable<labelPair, edge, Hash<edge> >, foo, iter)
246 These convenience macros are also generally avoided in other
247 container classes and OpenFOAM primitive classes.
249 *** Splitting Over Multiple Lines
251 **** Splitting return type and function name
252 + split initially after the function return type and left align
254 + do not put =const= onto its own line - use a split to keep it with
255 the function name and arguments.
260 const Foam::longReturnTypeName&
261 Foam::longClassName::longFunctionName const
267 const Foam::longReturnTypeName&
268 Foam::longClassName::longFunctionName const
274 const Foam::longReturnTypeName& Foam::longClassName::longFunctionName
281 const Foam::longReturnTypeName& Foam::longClassName::
282 longFunctionName const
285 + if it needs to be split again, split at the function name (leaving
286 behind the preceding scoping =::=s), and again, left align, i.e.
291 const Foam::longReturnTypeName&
292 Foam::veryveryveryverylongClassName::
293 veryveryveryverylongFunctionName const
296 **** Splitting long lines at an "="
302 longClassName.longFunctionName(longArgument);
309 longClassName.longFunctionName
320 longClassName.longFunctionName(longArgument);
326 variableName = longClassName.longFunctionName
341 a < b, a > b, a >= b, a <= b
345 + splitting formulae over several lines
347 Split and indent as per "splitting long lines at an ="
348 with the operator on the lower line. Align operator so that first
349 variable, function or bracket on the next line is 4 spaces indented i.e.
358 This is sometimes more legible when surrounded by extra parentheses:
369 + splitting logical tests over several lines
371 outdent the operator so that the next variable to test is aligned with
372 the four space indentation, i.e.
386 + For readability in the comment blocks, certain tags are used that are
387 translated by pre-filtering the file before sending it to Doxygen.
389 + The tags start in column 1, the contents follow on the next lines and
390 indented by 4 spaces. The filter removes the leading 4 spaces from the
391 following lines until the next tag that starts in column 1.
393 + The 'Class' and 'Description' tags are the most important ones.
395 + The first paragraph following the 'Description' will be used for the
396 brief description, the remaining paragraphs become the detailed
406 A class for specifying the documentation style.
408 The class is implemented as a set of recommendations that may
412 + The class name must be qualified by its namespace, otherwise Doxygen
413 will think you are documenting some other class.
415 + If you don't have anything to say about the class (at the moment), use
416 the namespace-qualified class name for the description. This aids with
417 finding these under-documented classes later.
422 Foam::myUnderDocumentedClass
425 Foam::myUnderDocumentedClass
429 + Use 'Class' and 'Namespace' tags in the header files.
430 The Description block then applies to documenting the class.
432 + Use 'InClass' and 'InNamespace' in the source files.
433 The Description block then applies to documenting the file itself.
441 Implements the read and writing of files.
444 *** Doxygen Special Commands
446 Doxygen has a large number of special commands with a =\= prefix or
447 (alternatively) an =@= prefix.
449 The =@= prefix form is recommended for most Doxygen specials, since it
450 has the advantage of standing out. It also happens to be what projects
451 like gcc and VTK are using.
453 The =\= prefix form, however, looks a bit better for the =\n= newline
454 command and when escaping single characters - eg, =\@=, =\<=, =\>=, etc.
456 Since the filtering removes the leading 4 spaces within the blocks, the
457 Doxygen commmands can be inserted within the block without problems.
465 Implements the read and writing of files.
467 An example input file:
477 Within the implementation, a loop over all patches is done:
479 forAll(patches, patchI)
481 ... // some operation
486 *** HTML Special Commands
488 Since Doxygen also handles HTML tags to a certain extent, the angle
489 brackets need quoting in the documentation blocks. Non-HTML tags cause
490 Doxygen to complain, but seem to work anyhow.
493 + The template with type =<HR>= is a bad example.
495 + The template with type =\<HR\>= is a better example.
497 + The template with type =<Type>= causes Doxygen to complain about an
498 unknown html type, but it seems to work okay anyhow.
501 *** Documenting Namespaces
503 + If namespaces are explictly declared with the =Namespace()= macro,
504 they should be documented there.
506 + If the namespaces is used to hold sub-models, the namespace can be
507 documented in the same file as the class with the model selector.
511 documented namespace 'Foam::functionEntries' within the
512 class 'Foam::functionEntry'
515 + If nothing else helps, find some sensible header.
519 namespace 'Foam' is documented in the foamVersion.H file
523 *** Documenting typedefs and classes defined via macros
525 ... not yet properly resolved
528 *** Documenting Applications
530 Any number of classes might be defined by a particular application, but
531 these classes will not, however, be available to other parts of
532 OpenFOAM. At the moment, the sole purpuse for running Doxygen on the
533 applications is to extract program usage information for the '-doc'
536 The documentation for a particular application is normally contained
537 within the first comment block in a /.C/ source file. The solution is this
538 to invoke a special filter for the "/applications/{solver,utilities}/"
539 directories that only allows the initial comment block for the /.C/ files
542 The layout of the application documentation has not yet been finalized,
543 but foamToVTK shows an initial attempt.
545 *** Orthography (an opinion)
547 Given the origins of OpenFOAM, the British spellings (eg, neighbour and
548 not neighbor) are generally favoured. For code sections that interact
549 with external libraries, it can be useful to adopt American spellings,
550 especially for names that constitute a significant part of the external
551 library - eg, 'color' within graphics sub-systems.
553 Both '-ize' and the '-ise' variant are found in the code comments. If
554 used as a variable or class method name, it is probably better to use
555 '-ize', which is considered the main form by the Oxford University
563 The word "its" (possesive) vs. "it's" (colloquial for "it is" or "it has")
564 seems to confuse non-native (and some native) English speakers.
565 It is better to donate the extra keystrokes and write "it is" or "it has".
566 Any remaining "it's" are likely an incorrect spelling of "its".