Skip to content

Coding conventions

Libor Pecháček edited this page Dec 14, 2020 · 15 revisions

This is a list of coding conventions used by the OpenOrienteering Mapper project, roughly ordered by importance. It is not demanded to obey these rules slavishly, but most of all when changing existing code they should help to retain a clear formatting.

Key guidelines

File names

Use lowercase with words separated by underscores, for example some_project_file.cpp. Use .h for headers, .cpp for implementation.

Includes

Includes are separated into up to four blocks:

  1. For .cpp files, the include for the respective header. Just the filename, no path.
  2. Includes for standard library headers. Prefer C++ includes over C ones.
  3. Includes of third party headers (Qt etc.).
  4. Includes of other headers in this project. Specify the path relative to the src directory, even if the file is in the same directory.

Inside the blocks, use alphabetic order. (Qt Creator can sort selected lines, shortcut Alt+Shift+S.) However, it is preferred to put Qt headers for global definitions (<Qt>, <QtGlobal> etc.) before Qt headers for particular types (<QLabel> etc.).

Include what you use: For any feature you are using, either forward declare the feature if this is possible and sufficient, or include the relevant header. Do not rely on transitive inclusion.

Example for a file called "this_file.cpp":

#include "this_file.h"

#include <memory>
#include <cassert>

#include <QtGui>
#include <liblas/liblas.hpp>

#include "core/map.h"
#include "gui/map/map_widget.h"

Indentation

Use tabs with a width of 4.

Naming

  • Variable names are lowercase and words are separated with underscores: num_objects
  • Class, struct, enum and enum member names are in camel case and start with an uppercase letter: PointSymbol
  • Method names are in camel case and start with a lowercase letter: PointSymbol::setName(const QString& name)

Example:

class ExampleClass
{
public:
    void getSomethingDone();
    float makeCrazier();

private:
    int some_integer;
    float degree_of_craziness;
}

Braces

Braces are normally opened on the next line, except in a few cases. Examples:

// Normal case
if (random)
{
    cutGreenWire();
    explode();
}
else
{
    cutRedWire();
    implode();
}

// Special case
inline void veryShortMethod() { veryShortContent(); }

Exceptions

Avoid exceptions. However, there may be good reasons to use exceptions for unexpected error conditions.

Qt5-style connect()

Use the pointer-to-member-function style for connects where possible.

Support constness

Provide and use const implementations of methods where possible. Similar for const references.

Modern C++

new / delete

Forget about old-school resource management with delete-laden destructors and use the modern approach.

Pointers

Unless interfacing with Qt (QObject ownership), consider using std::unique_ptr/std::make_unique.

Variable, class member and parameter initialization

Use C++11 curly brace value and zero initialization. The preferred syntax of class member and variable initialization includes the equal sign, i.e. T t = {}.

Examples:

  • Default parameter value. Unlike Qt, we do not repeat the parameter type name.
ColorDialog(const Map& map, const MapColor& source_color, QWidget* parent = nullptr, Qt::WindowFlags f = {});
  • "Zero" parameter value for a function/method call.
editor->setText({});
  • Variable and class-member init. Any data type that lacks a default constructor should be initialized in this way to prevent use-before-set situation.
MapCoord snap_mark = {};

Almost always auto (AAA)

Use of auto for local variables is encouraged. Watch out for the difference between auto and auto* when using pointer variable.

Lambdas

Use of lambdas for local helpers is encouraged.

constexpr, noexcept, move-semantics

The proper implementage and usage of constexpr, noexcept and move semantics is encouraged.

Auxiliary guidelines

Common C++ guidelines

The following guidelines provide excellent advice, although not all points apply to Mapper:

Containers

  • Keep in mind that at least the Android port may run under low memory conditions.
  • Prefer (carefully chosen) standard library containers over Qt containers.
    • Prefer std::vector over QHash and friends for small structures (hint: strong locality, low memory fragmentation).
    • However, when interfacing with Qt, there is no need to enforce additional conversions.
  • Beware the expensive detaching of implicitly shared Qt containers on some operations, e.g. in range-for loop.

Think internationalization

Please make sure to use tr() on all strings which need to be translated. See Translation for more information.

CMake guidelines

Git guidelines

How to Write a Git Commit Message

In the OpenOrienteering project, it is convention to start the subject line with the name of the unit (class, file, directory) which is the (only or main) subject of changes, followed by colon. For the remainder, please note "the seven rules of a great Git commit message":

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how

Read more at https://chris.beams.io/posts/git-commit/.