When contributing to CEPS, developers must comply with the following set of coding conventions. Some of these rules raise an issue when analyzed with cppcheck and sonarqube, which contributes to the total number of "code smells" and lowers the maintanability rating. Additionnally, you can find on this page information on how code coverage is measured. Source files within the tests
directory are not analyzed.
Naming
- CEPS uses the CamelCase naming convention.
- Variables, functions and methods must start with a lower case letter.
- Protected and private attributes of classes must be prefixed with
m_
.
- Class names must start with an upper case letter.
- Function and class names should not exceed 30 characters.
- Abstract base classes must be prefixed with
Abstract
.
- When writing cpp files, use the full name of methods, including namespace prefix, instead of putting them in a namespace block.
Indentation, lines, alignment
- Code must be indented with blocks of 2 spaces. No tabulations must be present in any file.
- Blocks must be opened and closed as follows:
statement (condition)
{
}
- The
public, protected, private
sections of a class declaration must be indented within the class block. The methods and attributes within these blocks must be indented as well (4 spaces from the start of the line).
- A single line must not contains more than one statement.
- The return type of a function and templates must be written on seperate lines than the full name of the function (including class or namespace prefix)
- Lines should not exceed 100 characters. Line breaks are authorized, alignments of code are welcome (praise vim's block selection).
- When a list of arguments of a function is too long to fit in a single line, use the following syntax, even in header files:
template <typename T1>
void
classOrNamespace::myFunctionWithManyParameters(
type1 arg1,
longtype2 arg2,
longlongtype3 arg3
)
{
}
- An extra empty line must be added at the end of the file for better parsing of analysis tools.
Comments
- All declared elements must be documented using a doxygen comment.
- The
@param
arguments of doxygen comments for funtions are not mandatory, especially when the argument names are explicit
- All comments should be inlined with
//
for easier toggling between code and comments.
- All source files must contain the licence and authors header (see contrib/release/generateHeaders.py)
- All source files must contain a
\file
doxygen comment.
Types
- Even if it is not compliant to the C syntax of pointer declaration, the
*
and &
must be placed directly after the typename: const CepsReal& a; CepsVector<CepsReal*>* vec;
This makes identifying types of variables faster.
Templates
- Avoid excessive use of templates. Use class attributes instead, whenever possible.
- Prefer the keyword
typename
instead of class
in template declarations.
- Place template definitions in separate
.tpp
files that are included from the header file containing their declarations. You can still include the .hpp
from the the .tpp
to make your IDE recognize the symbols without affecting compilation.
Includes
- Specifiy the full path name from
src
for CEPS files.
- Use
#pragma once
instead of #ifndef
directives.
Debugging
- When debugging, if you want to print some information instead of using the debugger, use the
DISP
or DISPR
macros. They can take up to ten arguments, and display both the expression to print and its value. After debugging, make sure no other file than CepsIoMacro.hpp
and the documentation file of this page contain these macros.
Code coverage
Here are the compilation flags used to determine code quality:
-fPIC --coverage -Wall -Wno-long-long -pedantic -fdiagnostics-show-option -O1 -fno-inline -fno-omit-frame-pointer -fno-optimize-sibling-calls
Then, coverage is measured with the following options:
gcovr --exclude-unreachable-branches --exclude-
throw-branches -r . -x -o
ceps-coverage.xml
A namespace for all utility methods.
Here are some advice to improve coverage:
- Write very small unit tests limited to each implemented feature.
- Use utilities that are defined in the
common
directory, such as ceps::getNew
instead of the new
operator, the macros CEPS_ABORT
, CEPS_WARNS
, etc.
- Avoid boolean conditions that are too complicated as they create lots of branches. For example replace
CepsBool isOk = s==
"YES" or s==
"1" or s ==
"TRUE" or s ==
"ON" or s==
"OK"
by
std::vector< _Type, _Alloc > CepsVector
C++ vector.
CepsBool contains(const CepsVector< _Type, _Alloc > &vec, const _Type &item)
Tells if vectors contains a given item.
Many others
- Just follow what is already in place.
- If you encounter some bits of code that do not follow these rules, please contribute by formatting them appropriately. Thanks.