SG++
Developer Manual

On this page, we describe best coding practices for SG++.

All code has to be documented in such a way that functions, classes, and all other entities appearing in this documentation are easily understandable for all other developers.

Overview

Testing

We have both Boost unit tests (in C++) and Python unit tests. The tests can be found in the test subdirectory of each module. New tests should be written preferably with Boost. However, there is some extra functionality in Python which can be tested only in Python, of course.

If you modify existing code, do not forget to make sure that no new errors are introduced. If you write new functionalities, do always add unit tests for each functionality!

Doxygen

The documentation has to be Doxygen compatible. Doxygen tags must be used in the Java-style way, i.e., starting with @.

During development tags like @todo should be used wherever applicable. They are then listed on the Todo page.

Different source files can be grouped together in so-called modules. The link to the page listing all modules can be found in the navigation bar of the documentation. Note that this page and the page listing all examples are autogenerated when running SCons.

Please correct any warnings or errors that appear when creating the documentation with Doxygen!

See also
Doxygen manual
Documenting the code with Doxygen
Special Doxygen commands

Usage

Executing doxygen in the main folder creates the Doxygen documentation in the subfolder doc. The settings for Doxygen are taken from Doxyfile. This file is automatically created based on Doxyfile_template each time scons is exectued, therefore, for modifications, please change Doxyfile_template instead.

Coding

Comments

The complete code has to be commented elaborately. The comments, together with the identifiers, have to enable others to familiarize with the code quickly. Header files have to be commented completely. In source files, it suffices to comment the codelines. The comments have to be verbose enough so that one can understand what is going on without reading the code! Please use Doxygen-compatible comments for classes and methods.

Style

Compliance with the style guide is important to write good code. A style guide is more than a bunch of indentation rules; rather, it is the art of creating easily reusable, understandable, and refactorable code.

We adhere mostly to the Google C++ Style Guide. However, there are some exceptions:

  • We use a maximum line length of 100 characters (instead of Google's 80 characters).
  • We allow functions to have non-const reference arguments for output parameters (Google's style guide would require to use pointers instead).

To ensure compliance with most rules of the style guide, Google's Python script cpplint.py is used (in a slightly modified version located in tools/cpplint.py). By default, on every invokation of SCons, it is automatically run on each *.cpp or *.hpp file which was modified since the last run of SCons. If issues are found, warnings of the following form are printed on the screen:

base/src/sgpp/globaldef.hpp:95: warning: Namespace should be terminated with "// namespace sgpp"  [readability/namespace] [5]

The number in brackets at the end indicates the confidence that the line is indeed a problem, using a scale from 1 to 5 (5 means certainness). Be aware that some warnings are filtered out deliberately to implement the exceptions above.

Currently, SCons generates empty *.lint files whose modification times are used to track which files have to be analyzed. Delete the lint files to retrigger the analysis of all code files:

find base/src/ -name '*.cpp.lint' -or -name '*.hpp.lint' | xargs rm

You can deactivate the style checking (and thus the creation of the *.lint files) by setting RUN_CPPLINT=0 on the SCons command line.

You can also use a formatter tool to automatically format your code which should fix most of the "easy" style warnings (indentation, line length, etc.). We recommend using clang-format, which can be installed on an Ubuntu system using

apt-get install clang-format-3.7

You can format all files in-place with a command like the following:

find base/src/ -name '*.hpp' -or -name '*.cpp' | xargs clang-format-3.7 -style=file -i

The configuration of the formatter is done via the file .clang-format at top level.

If you are developing with Eclipse, clang-format and cpplint can also be applied automatically on every file save by using a slightly modified version of the Eclipse plugin CppStyle, which is also included in the tools directory of SG++ (the modification was necessary since CppStyle does not analyze hpp files). To install the plugin, simply copy the *.jar to the dropins subdirectory in your Eclipse installation location (i.e., not your workspace directory). The configuration is then done by clicking on WindowPreferencesC/C++CppStyle. Enter the paths to the clang-format executable (e.g., in /usr/bin) and to the cpplint.py script (tools/cpplint.py). Finally, check Enable cpplint and Run clang-format on file save.

Naming

Naming:

  • Directories: all lowercase, underscore separated (e.g., test_problem)
  • Classes: camel case starting uppercase (e.g., GridStorage)
  • Functions, Methods, Variables: camel case starting lowercase (e.g., getLevel)
  • Constants, Defines: all uppercase, underscore separated (e.g., INITIAL_LEVEL)
  • Nothing starts with underscores (only system/builtin/compiler).

Don'ts

Don't…

  • … include sgpp_MODULENAME.hpp. Only include the header files you require to avoid long building durations.
  • … use includes with quotation marks (include "Foo.hpp"); use angle brackets instead (include <Foo.hpp>).
  • … use relative include paths (include <../Foo.hpp>). Always use absolute paths (include <sgpp/base/Foo.hpp>).
  • … use using namespace.
  • … use tabs, use two spaces instead! Please configure your editor in order to do so!

Creating new modules

T.b.d.