Skip to content
Matthias Urlichs edited this page Jan 7, 2019 · 5 revisions

In order to clean up this code base, one should employ the following conventions when contributing to this project. Note that this list is incomplete in its current form. I urge you to evaluate and extend these guidelines.

Code layout

KNXD is written in C++. It has originally been formatted using "indent", which unfortunately knows only C but next to nothing about C++, thus some of the whitespace in the code doesn't look at all like idiomatic C++.

Please try to adhere to the formatting of existing code as much as possible, or at least as much as you're comfortable with. Specifically, please adhere to the two/four-space indent scheme:

if (x)
  {
    more_statements;
    more_statements;
  }
else
  single_statement;

Header units

Files containing header units should carry a file extension .h.

You must use a header guard in the form of KNXD_PATH_TO_FILE_H_ (e.g. KNXD_LIBSERVER_EIBNETIP_H_) to prevent collisions when including files twice.

You may

  • define type aliases,
  • define data structures,
  • declare methods and non-static functions,
  • define inlinable methods and functions,
  • define template methods and functions

You must not

  • resolve namespaces (e.g. using namespace xyz),
  • define non-inlinable methods and functions,
  • define static functions

Include statements

There are two types of #include directives. Use #include <...> to include a global header unit (e.g. standard library or external dependency). In order to include header units which are part of this project, you must use the form #include "..." where ... represents the path relative to the including file.

"#ifdef"s

You may use "#ifdef" directives for

  • guard macros (#ifndef foo / #define foo … / #endif)
  • conditionals on a specific compiler (cf. "#ifdef gnuc" in src/common/types.h)
  • conditionals on "HAVE_XXX" as discovered by autoconf.

You may not use operating system specific conditionals: they tend to stop working when you switch compilers, cross-compile, or build with an alternate libc.

You may check for the existence of a specific macro to decide on which implementation to use (cf. "#ifdef SIOCGIFHWADDR"). However, do not use the non-existence of a macro to decide whether to include some additional file: your includes should be unconditional, or depend on discovery by autoconf.

Docstrings

Use docstrings to document features. Simply prepend a docstring comment to the declaration of your function, method or data type. If your feature consists of a definition only, you may also attach it to the definition.

Example with functions:

/**
 * My function does X with the parameters 'param1' and 'param2'
 * to achieve Y.
 */
int my_function(int param1, int param2);

Example with data types:

/**
 * A short description of 'MyStruct'
 */
class MyStruct {
public:
	/**
	 * Describe 'some_field1' here
	 */
	int some_field1;

	/**
	 * Describe what 'perform(int)' does here
	 */
	void perform(int x);
};

Clone this wiki locally