Programming Reference:Cpp Coding Style
Appearance
We maintain a loose set of guidelines/rules that is aimed at readability and maintenance efficiency. These rules are not obligatory, but we ask contributors to consider them before handing in their code.
Line Formatting
- No tab characters (please configure your editor to insert spaces instead).
- Indentation in steps of 2 or 3 space characters.
- Opening braces have their own line, aligned with the previous line; corresponding closing braces are placed on their own lines, at the same character position as the opening brace.
- For function definitions, return types appear on their own line, such that the function name is first in its line.
Naming
- ALL_UPPERCASE_NAMES are reserved for preprocessor macros.
- CamelCase (uppercase letters inside words) is used to indicate word boundaries.
- Class names and namespaces begin with uppercase letters: MyNameSpace, TheClass.
- Local variables and function arguments begin with lowercase letters: theCounter, inSomeInput.
- Data members (properties) of true classes are private, and accessed via Accessor Functions.
- Setters use the prefix "Set" followed by the property's name: SetValue(). Setter functions should also return a non-const reference to the data object itself rather than void, this allows for chaining as in
float result = MyComputation().SetOrder( 5 ).SetDepth( 10 ).EvaluateAt( 4 ); - Getters use the name of the property: Value(). Omitting the "Get" prefix allows the programmer to treat getters and reference accessors identically, as far as read access is concerned.
- Reference Accessors use the name of the property, and are provided in a doubly const and a non-const version. This is important to allow const access from const object references, and to discriminate between read and write accesses (note the mPossiblyChanged flag):
const int& Value() const { return mValue; }int& Value() { mPossiblyChanged = true; return mValue; }
- Setters use the prefix "Set" followed by the property's name: SetValue(). Setter functions should also return a non-const reference to the data object itself rather than void, this allows for chaining as in
Name prefixes
Prefixes should carry information about the scope and usage of a variable but not its type. The rationale behind representing scope is to avoid accidental hiding of names from a wider scope by names with a narrower scope, which may lead to difficult-to-detect bugs. Representing usage makes it easier to maintain an overview over householding tasks, such as calling delete on pointers whose objects are owned by the code under review. Not representing type avoids name and type going out of sync.
Suggested prefixes are
- m for class data members,
- s for static class members and static variables,
- g for globals,
- c for constants,
- p for pointers,
- fp for function pointers,
- in for function input arguments,
- out for function output arguments,
- io for function arguments used for input and output.
Variable Declaration
- Always use the narrowest possible scope for a name to avoid side effects.
- Always initialize variables of elementary type at declaration resp. constructor. Examples of elementary types are int, float, or const char*.
Memory Allocation
- Allocate objects from the stack rather than the heap unless there is a good reason to use the new operator. This avoids memory leaks.
- Use STL containers rather than allocating arrays with new[]. This eliminates a number of possible errors (initialization, allocation, deallocation).
Pointers and References
- Use references rather than pointers wherever possible.
- When using pointers, treat the NULL case gracefully.
Control Flow
- Avoid goto, break outside switch-case blocks, and multiple return statements.
- Multiple return statements are OK when they provide a readable alternative to deeply nested conditions.
Example Function
void
MyClass::MyFunction( const SomeClass& inTheInput, int& outTheResult )
{
outTheResult = mSomeDataMember;
for( int i = 0; i < inTheInput.NumIterations(); ++i )
{
int k = 4;
while( --k > 0 )
outTheResult -= k;
}
}