1

Code Arrangement

1.1
Don’t put method definitions (including empty) in .h files.
1.2
Put each class declaration in an extra .h file.

2

Code Formatting

2.1
Use UTF-8 encoding for all source files.
2.2
Indent code by 4 spaces (no tabs).
2.3
Use < and > for external libraries as well as local public includes.
2.4
Be consistent within your own code and the project’s code that you are working on.
2.5
For published code, adhere to our code formatting guide [more]

3

Type Naming

3.1
Use CamelCase for class and enum names.
3.2
Use CamelCase beginning with a lowercase letter for function and method names.
3.3
Start names of classes having pure virtual methods with Abstract.
3.4
Use CamelCase for files containing structs, classes, or enums.
3.5
Omit prefixes for getters, e.g., get. [more]
3.6
Add set prefix to setters. [more]
3.7
Add m_ prefix to member variables, s_ to static member variables, t_ to thread-local variables, and g_ to global variables.
3.8
Don’t add prefixes to local variables and formal parameters.

4

Designing Classes

4.1
As a default, use public inheritance.
4.3
Consider making the public interface non-virtual.
4.4
Avoid virtual inheritance.
4.5
Avoid friend declarations.
4.7
Use struct for Plain Old Data structures (POD), class when using object-oriented features.
4.8
Don’t use nested classes in a public interface. (They cannot be forward declared.)
4.9
Adhere to the given declaration order. [more]

5

Designing Interface Signatures

5.1
Follow the table of parameter passing. [more]
5.2
Declare member functions that do not change the member variables const.

6

Include Dependencies

6.1
Almost always use forward declarations.
6.2
Avoid use forward declarations for the following libraries: STL, glm (use glm/fwd.hpp and iosfwd instead).
6.3
Adhere to the following include order: corresponding header (if applicable), std headers, low-level third-party headers, high-level third-party headers, local headers.
6.4
Use #pragma once instead of #define guards.

7

Implementation Design

7.1
Prefer guard clauses over nested conditionals.
7.2
Use assertions as a means to protect against self-induced programming mistakes.
7.3
Use C++ style casts (static, dynamic, reinterpret) for class pointers, prefer for primitive data types.
7.4
Initialize all declared variables (especially basic types like bool, int and float).
7.5
Prefer the standard template library (especially the algorithms library) over custom code. [more]
7.6
Make use of suffix literals.
7.7
Prefer range-based for loops over iterators over index based access.
7.8
Avoid owning raw pointers, new and delete (Smart pointers are the default). [more]
7.9
Use non-owning raw * and & for parameters and return values. [more]
7.10
When passing pointers, handle passing a nullptr.
7.11
Declare constant variables const. [more]
7.12
Prefer small and focused functions.
7.13
Do not nest lambdas.
7.14
Avoid mutable.
7.15
No using namespace in header files.

8

Comment Style

8.1
For APIs of published code follow the comment style guidelines. [more]
8.2
When creating new class files, use this template.
8.3
Always add class and public member comments.
8.4
Use ToDo comments for code that is temporary, a short-term solution, or good-enough but not perfect. (Form: // ToDo <description>)
8.5
Add comments in tricky, non-obvious, interesting, or important parts of your implementation code.
8.6
Do not restate code in comments.
8.7
Do not use commenting out as a mean to archive code; we use version control systems.

9

General C++11 Features

9.1
Use override for overridden methods.
9.2
Use auto where applicable (see right-hand style). [more]
9.3
Capture variables in lambdas explicitly.
9.4
Use enum classes and specify underlying type.
9.5
Use = delete as a mean to remove auto generated class methods.
9.6
Use using instead of typedef.
9.7
Use uniform initialization except for container constructors where you don’t want to pass elements. [more]
9.8
Use std::array instead of c arrays.
9.9
Don’t use constant expressions (constexpr) as they are not fully supported yet by all compilers.
9.10
Use nullptr for null pointers, 0 for numbers; never use NULL.

10

Templates

10.1
Always split template declaration and definition (put definitions in .hpp file).
10.2
Include implementation file in header file and vice versa.

11

Cross-platform Compatibility

11.1
Assure all dependencies are available cross-platform.
11.2
Always use c-prefixed includes for C standard library headers (e.g., #include <cmath>).
11.3
Separate complex platform specific code into files and select them via the build system.

12

Library Design

12.1
Public headers belong in source/<library name>/include/<library name>/.
12.2
Private headers belong in source/<library name>/source/.

13

Common Mistakes

13.1
Use auto capture lambdas (std::function is a functor wrapper not its type.)
13.2
dynamic_cast is not the default for down casts; if you know the type, use static_cast.
13.3
Be aware that resizing std::vectors invalidates iterators. [more]
13.4
Avoid allocating container classes on the heap.
13.5
Make destructors of base classes virtual.
13.6
Export only public classes, structs and, functions (<library uppercase name>_API).
13.7
Don’t export templates and enums (it is illegal anyway).

14

Performance Considerations

14.1
Avoid continous heap memory allocations in large loops.
14.2
Inline methods and functions only after profiling.
14.3
Use pre-incrementation as default.
14.4
14.5
Prefer to perform costly operations lazy.
14.6
Make std::vector your favorite container type.

15

Miscellaneous

15.1
Check your design for heavy use of down casts. It indicates bad design.