Coding Style
C++ Source Formatting and Style
1 Line Length
- Source code lines should be less than 81 characters
Exceptions:
#include
statements- header guards
- comment lines containing a literal URL
2 Whitespace
- Unix-style linebreaks (‘\n’), not Windows-style (‘\r\n’)
- Use only spaces for indentation, and indent 2 spaces at a time
- Never use tab characters
-
Contents of each new variable scope should be subject to an additional level of indentation
Exception:
- scopes resulting from namespace declaration
-
Prefer to include a space following opening parenthetical characters and preceeding closing parenthetical characters, respectively, e.g.
template< typename T > void print( T t ){ std::cout << t << std::endl; }
-
Prefer to break before binary operator for statements spanning multiple lines, e.g.
if ( reallyLongVariableName && otherLongVariableName ){ }
3 Control structures
- Prefer 1TBS: left brace at end of first line, cuddle else on both sides
- Always brace controlled statements, even a single-line consequent of an
if
,else if
, orelse
Example
if (...) {
} else if (...) {
} else {
}
if (...){ /* single line */ }
while (...) {
}
do {
} while (...);
for (...; ...; ...) {
}
4 Naming Conventions
- Prefer
UpperCamelCase
when naming classes, structs, and enumeration classes - Prefer
lowerCamelCase
when naming variables, functions, and namespaces - Prefer
SCREAMCASE
when naming preprocessor constants and macros -
Avoid names referencing equation variables, preferring more descriptive names, e.g.
double mu /* bad */, angleCosine /* good */; double sigmaTotal /* bad */, totalCrossSection /* good */;
Exceptions:
- prefer capital letters for abbreviations in names, falling back to standard conventions e.g. myENDFParser
- for variables refer to quantities specified in external documentation, prefer the conventional capitalization scheme, e.g. double QValue
5 Documentation
- Classes, structs, and functions are to be annotated for the Doxygen documentation generation tool
- Avoid providing examples embedded in comments and/or annotations, preferring examples in the form of unit tests
-
Prefer the Javadoc format for source annotations, e.g.
/** @brief An ordered sequence of signed integers */ class IntegerList;
- When forward declaring a class, struct, or function, annotate the forward declaration, but with the brief only
- do not repeat the brief in the class, struct, or function definition
- Annotations aside, comments should not be used to describe what code does or how it works
- prefer literate, self-documenting source code
-
When faced with an algorithm or design choice, comments preserving relevant infomation and reasoning are welcome, especially under circumstances when the choice might be counter-intuitive e.g.
/* A binary search turned out to be slower than the Boyer-Moore algorithm for * the data sets of interest, thus we have used the more complex, but faster * method even though this problem does not at first seem amenable to a string * search technique. */
6 Class Conventions
public
,private
, andprotected
are not subject to indentation beyond theclass
keyword-
Use name overloading when defining getter and setter methods, e.g.
class CrossSection { public: /* good */ const std::vector<double>& energies const (); /* bad */ /* const std::vector<double>& * getEnergies const (); */ /* good */ void energies( std::vector<double>&& E ); /* bad */ /* void * setEnergies( std::vector<double>&& E ); */ };
-
Prefer to access non-static class and struct member variables and methods through the
this
pointer, e.g.double MyClass::method( int i ) const { const auto foo = this->otherMethod( i ); return foo * this->fieldVariable; }
7 Type Sigils
-
Prefer to snuggle type sigil to the base type rather than the variable name in variable declarations, e.g.
T* p; /* good */ T& p; /* good */ T *p; /* bad */ T* p, q; /* OOPS put these on separate lines */
8 Miscellaneous
- Prefer
nullptr
toNull
or0
for pointers - When testing a pointer, prefer
(!myPtr)
or(myPtr)
; don’t usemyPtr != nullptr
ormyPtr == nullptr
- When testing a boolean value, avoid
(x == true)
or(x == false)
. Use(x)
or(!x)
instead -
When specifying header guards, begin with the fully-qualified include path within the respective project, move to
SCREAMCASE
, then substitute_
for/
,.
, and-
, e.g./* acetk/implementation/ACETable.hpp */ #ifndef ACETK_IMPLEMENTATION_ACETABLE_HPP #define ACETK_IMPLEMENTATION_ACETABLE_HPP #endif