-
Notifications
You must be signed in to change notification settings - Fork 13
google style guide
The following guidelines are mostly based on the Google C++ Style Guide. We modified it, because we don't agree with all of the policies from the Google Style Guide.
[TOC]
Every header file has to come with a #define
guard of the following form:
#ifndef <PROJECT>_<PATH>_<FILE>_H_
#define <PROJECT>_<PATH>_<FILE>_H_
...
#endif /* <PROJECT>_<PATH>_<FILE>_H_ */
DON'T use #pragma once
- Inputs
- Outputs
All #include
s have to go to the top of the file (after the include guard). Use the following order:
- C library
- C++ (STL) library
- other libraries
- includes from this project
DON'T use the using
directive.
Always use namespaces: everything outside of a main
file must be enclosed in the project's namespace.
Try to avoid and use only if absolutely necessary.
Try to avoid global functions. Prefer nonmember functions within a namespace or static member functions to global functions.
Place a function's local variables in the narrowest scope possible, and initialize variables in the declaration.
Static or global variables of class type are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction. However, such variables are allowed if they are constexpr
: they have no dynamic initialization or destruction.
Don't implement complex algorithms in class methods. Rather implement them as nonmember methods inside the projects namespace (or sub-namespace).
-
Avoid doing complex initialization in constructors (in particular, initialization that can fail or that requires virtual method calls).
-
Always declare and define constructors for your classes that initialize ALL member variables that are not initialized in-class. If you do not, the default constructor might not properly initialize all member variables.
-
Provide a copy constructor and assignment operator only when necessary. Otherwise, disable them with
DISALLOW_COPY_AND_ASSIGN
. -
Use delegating and inheriting constructors when they reduce code duplication.
Use a struct
only for passive objects that carry data; everything else is a class
.
- All pure interfaces must end with the
Interface
suffix. - Multiple inheritance is only permitted when at most one of the base classes has an implementation, all other bases classes must be pure interfaces.
Do not overload operators except when strictly semantically equivalent.
Make data members private
and provide access to them via getter and setter methods.
Example:
class Foo
{
public:
int getBar();
void setBar(int bar);
private:
int bar;
}
Prefer small functions, don't implement complex algorithms in class member functions.
All parameters passed by reference must be labeled const
. Try to use references where ever possible (avoiding unnecessary copies).
Use overloaded functions (including constructors) only if a reader looking at a call site can get a good idea of what is happening without having to first figure out exactly which overload is being called.
We do not allow default function parameters.
Minimize the usage of friend
classes and functions.
We will use C++ exceptions.
Use static_cast<>()
.
DON'T use C-style casting (i.e. y = (int)x; y = int(x);
).
Use prefix form (++i
) where ever they are interchangeable (i.e. loops).
- Use
constexpr
andconst
whenever it makes sense.
Allowed are only the base types:
char
signed char
int
unsigned int
Use int
s only when the actual bit width is not of importance (i.e. 32 bit vs. 64 bit does NOT matter). If in doubt, use the precise-width types (see below) instead.
NOT allowed are especially the types:
short
long
long int
long long
Use the precise-width integer types from <stdint.h>
instead, e.g. uint64_t
, int16_t
, etc.
TODO are we sure that our algorithm will only work on 64 bit?
Be aware of compatibility between these systems.
Avoid when ever possible. Use constexpr
functions, inline
functions and constexpr
variables instead.
Use the following literals for null:
- integers:
0
- reals:
0.0
- pointers:
nullptr
(avoid theNULL
macro) - chars:
'\0'
Use sizeof(varname)
instead of sizeof(type)
.
Use the auto
type for STL iterators inside of loops. Try to avoid auto
as much as possible otherwise. The auto
keyword is encouraged in situations like:
std::vector<int> a(10);
// use:
for (auto it : a)
{
// ...
}
// avoid:
for (std:vector<int>::iterator it : a)
{
// ...
}
// especially avoid the old for-loop style:
for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it)
{
// ...
}
You may use brace initialization, e.g.:
std::vector<int> a = {1, 2, 3, 5};
Usage of boost libraries is allowed.
We are using features of the C++11 standard.