Coding Standard
Automated Checking
The following rules can be checked automatically to a certain extent using a style checker based upon the Google-Code-Style-Guide cpplint tool. You may execute it via the stylecheck
target
make stylecheck
Files
-
Header-files must end with
.h
. -
Source-files must end with
.cpp
. -
Header-files having inline implementation end still with
.h
since it may change and we don't want to rename all include stmts then. -
For each class there is exactly one header- and one source-file.
-
A filename is identical with the corresponding classname extended by its filetypesuffix.
-
Never include
.cpp
files. -
Module directories start in lower case without leading
W
for OpenWalnut and follow then CamelCase
Comments
- There are no multiline comments which aren't doxygen comments (which starts with
/**
). We forbid e.g.:
/*
* INVALID comment
*/
- Each file contains a comment-header for several information, at the moment we want it to look like this:
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
- The phrase
//
should be used for commenting except for doxygen-comments. - ToDo comments must look like this:
// TODO(username): Disable this when #313 is fixed
- For each function (also not auto documented derived constructors, overloaded functions should be auto documented) there exists a short description (detailed if needed) directly in front of its declaration or definition in the header file. The tool doxygen creates a documentation from these descriptions. Such a description has the following form:
/**
* fill in documentation here
* \exception (exceptionname description of exception)|nothing
* \param parameter1 information about parameter1
* \param parameterN information about parameterN
* \tparam param1_T information about template parameter 1
* \tparam paramN_T information about template parameter N
* \retval return parameter descr. of param. used to return sth.
* \return nothing or return value specification
*/
You can produce a nice html documentation with doxygen by calling make docs
using your preferred shell when you are located in the base directory.
-
State the intention of each code passage that is not fool-proof through a comment. Same stands for variables/pointers etc.
-
For more hints on how to comment see here.
Includes
- Header-files contain header-guards to prevent multiple inclusion as shown below:
#ifndef FILENAME_H
#define FILENAME_H
// put the code here
#endif
-
Include orders are as follows:
- Generally try to avoid platform dependent includes, but if they are inevitable include them at first and in alphabethical order.
- C and C++ includes. Try to use C++ wrappers for old C headers e.g. use:
<cmath>
instead of<math.h>
. - Other library includes in alphabethical order.
- Project includes in alphabethical order.
-
Between every include block there is a newline, and after all includes there are two newlines.
#include <sys/time.h>
#include <cassert>
#include <string>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include "src/math/math.h"
Naming conventions
- All type names should start in upper case
- When using names containing more than one word, we use CamelCase.
- Names never start with a
_
. - Names permit conclusions on their meaning and they are pragmatic in their length.
- variable names
- Local variable names starts with a lower case letter
- Member variables always start with the prefix:
m_
and carry on like local variable names (starting with a lower case letter)
- class names
- starts with a
W
followed by an upper case letter. The upper caseW
indicates that this is a Open**W
**alnut class name. - Module classes don't contain the phrase
Module
instead they start with the prefixWM
- starts with a
- Module icons
- should have the same name as the Module classes except the extension or file suffix should be .xpm instead of .cpp.
Classes
- The
public
,protected
andprivate
labels are stated in this order and aren't indented - There are no implementations of methods in the class definition, except in template classes and if the method is inline.
- If the member function is inline, be sure it is very short, since otherwise it may bloat the code. Also take care that inline member functions are defined outside the class but inside the header (the reason to do so, was that then the class interface is much more readable):
class Nix
{
// ...
public:
void fooBar();
// ...
};
inline void Nix::fooBar()
{
...
}
- Member functions that do not change objects are always declared as
const
- Classes with virtual methods have a virtual destructor
Variables
- Variables are declared with a minimal scope.
- Pointers to local variables must not be returned.
Member Variables
- All rules from the Variable section apply also to this section too
- Never specify public member variables.
- For each member variable that is needed outside of this class, getter and setter member functions exists and have the prefix
get
orset
in conjunction with the name of the member variable starting with a capital letter, e.g.:getFooBar()
. - The only exception from this rule are getters for boolean member variables. They have to have the prefix
is
, e.g.:isEnabled()
. - Should have at least a brief doxygen description.
Functions
- Avoid functions with many (~5) arguments!
- Each functions should fit almost on a screen. Avoid long and complex functions!
- Use const references when dealing with large data structures!
- The semantic has to stay the same for overloaded operators.
- Use the argument type and name when prototyping functions!
- Every function has an explicit return type (void if necessary).
Member Functions
- All rules from the Function section apply also to this section too
- If a method returns some extra data in arguments then these are the first arguments of the method
- Arguments that don't change have always a
const
modifier - The name of the function and the return type stay in the same line
- The arguments can be distributed if necessary on several lines; the new line begins by a character behind the column of the opening bracket that the argument list initiates:
void myFunction( TypeA myParameterA,
TybeB myParameterB );
- After the opening parenthesis there has to be a space character and also one before the closing one.
- If there are no arguments then
()
is your friend. - Overloaded operators should maintain their intuitive meaning like the
+
-operator. - Contrary operators (like
==
and!=
) are defined in pairs, either both or none.
Formatting
- The curly brackets, which include a block, are on the same column and in their own line.
void foo( int bar )
{
if( something )
{
}
else if( some other )
{
}
else
{
}
}
- If there is just one statement for a if or else block then curly brackets are also required.
- The operators
*
and&
should be directly connected with the type name of the variable. - For type casting only
reinterprete_cast<>
,dynamic_cast<>
andstatic_cast<>
are allowed. Expression like(int*)pointer
are forbidden.
MyType* myPointer;
MyType& myReference;
MyType myCastPointer = reinterprete_cast<MyType*>( otherPointer );
- Do not use spaces when dealing with the operators
.
and->
myObject.myMethod();
myPointer->myMethod();
- Identation:
- should be space-only (no tabs, nor mixed), 4 spaces per level
- initializers of constructors should be in the line following the name of the constructor and indented one level
- a level is introduced by curly brackets: '{', and labels are on same height as the opening bracket, e.g.:
namespace xyz
{
class Pansen : public pansen
{
public:
void foo();
Pansen();
private:
class Inner
{
int bar();
};
bool m_dummy;
};
Pansen::Pansen()
: m_dummy( true )
{
}
} // end of namespace
- Binary operators like
+
are surrounded by one space in front of and one space behind the operator (exception: new line).
double a = b + c;
- There is no trailing whitespace.
- There are no
using namespace
statements, always use the full qualified namespace. - Code lines should not be longer than 130 characters (including white spaces).
- Comment lines should not be longer than 80 characters (including white spaces).
Loops
- There are no for-loops like
for(;;)
{
}
Use while( true )
instead.
- For-loops look like this:
for( int i = 9; i < 23; ++i )
{
//...
}
- You always have to use curly brackets even if there is only one statement
Flow control
- Never use
goto
!
Memory management
- Do not use C-style functions like
malloc
,free
,... ! - There are no global variables.
- Avoid memory leaks:
- Do not allocate memory and hope that someone else will free it!
- Use the square brackets when deleting arrays!
double* mySpace = new double[size];
delete[] mySpace;
- Use smart pointers when possible. (auto_ptr, shared_ptr, etc.)
Fault handling
- Use exceptions for error handling. An error is a state that is not expected when the function / method / object is used correctly.
- Catch exceptions always by reference
try
{
...
}
catch( WException& e ) // Note the ampersand!
{
...
}
- Do NOT use exceptions to return results. Even if you need to pass multiple recursion levels!
- Always check the return values of functions even if they seem to be foolproof!
Debugging
- Code which is only used for debugging purpose has to be enclosed by
#ifdef DEBUG
respectively#endif
. The enclosed code must not influence the correctness of the algorithm.
Numbers
- Floating point numbers between 1 and -1 are written with leading zero, i.e.
0.567
instead of.567
is required. - Floating point numbers without any decimal place are written with a trailing zero, i.e.
567.0
instead of567.
is required. - The above two rules imply
0.0
instead of0.
or.0
for a zero floating number.
Shader programming rules
- We use only GLSL shaders. Other shader languages like Cg are not allowed.
- Shaders for modules need to be placed in the directory "shaders", which is a subdirectory of your module source directory.
- Shaders for modules need to be prefixed with the module name.
- Fragment shader files must end with
-fragment.glsl
. - Vertex shader files must end with
-vertex.glsl
. - Geometry shader files must end with
-geometry.glsl
. - Example:
- Your module has the name "MyModule" and is in src/modules/myModule
- The shader's names needs to be "src/modules/myModule/shaders/WMMyModule-fragment.glsl" and "src/modules/myModule/shaders/WMMyModule-vertex.glsl"
GUI
- Strings containing names for GUI elements or elements that might show up in the GUI shall adhere to the text capitalization guidelines.