Menu

Coding rules

Anonymous Burkhard Schmidt Ulf Lorenz

Coding rules are subject to change over time, whenever we come across something that needs to be defined properly. In case of doubt, the existing code should give a best practice suggestion.

TDD

The most important single coding rule is the use of test-driven development (TDD). This is explained in depth on another page, and is mandatory.

Coding

A few rules to make the code look pretty and somehow consistent:

  • Opening brackets always start on the line of the indenting clause (if/for/while statement) or on the next line for function declarations. If the opening bracket on the same line looks confusing, put it on the next line for clarity, though.
  • The code following a flow control statement (if/for/while) should always be put in a separate code block (i.e., curly brackets), even if it is a single statement.
  • Document classes and functions with doxygen-style comments. Exceptions are functions that override those in a base class or are self-explanatory(basic getters, for example).
  • try to use as self-explaining function names as possible. We do not use punch cards any longer, so a function name may exceed 8 characters.
  • Use the new C++-11-style unified initialization wherever possible, i.e., with curly brackets instead of normal brackets for constructor parameters. The exception are tests, where the test macros sometimes do not like it; this you will notice.
  • put template parameters on a separate line
  • if you override a function, always declare this function with the "override" keyword
  • whenever possible, use the new C++-11 auto syntax. There are two exceptions to the rule: the type should be explicitly declared for primitive data types (to specify the precision), and for tensor classes (the tensor libraries uses some type-casting functions to guarantee coherence of data).
  • never hold onto a std::function object. It may refer to Python objects/functions, in which case there may be lifetime issues. If a std::function is given as function argument, it must be used directly in the called function.

Design

Some guidelines when creating new classes and such:

  • Use abstract base classes for marker interfaces as in Java from which you then derive the implementations.
  • Try to avoid creating templated classes or functions.
  • All references between entities should be via pointers, and all such pointers should be wrapped in shared_ptr. This relieves the final user of most memory management. Also, use std::make_shared as default when creating objects (e.g., in tests).
  • Code should be typically defensive, and capture errors aggressively
  • Try to be aggressive with making functions const, and using const references as arguments.
  • Make functions short (<= 20 lines or so), and seriously consider redesigning if this does not work.
  • As a general rule, use forward declarations in header files instead of including other headers. Try to encapsulate external dependencies and do not include then in the header (exception: the tensor library) to keep compile times short.

Testing

Coding rules specific to tests:

  • Use asserts instead of expects; if a test fails, it should fail hard.
  • Make short self-explanatory tests. Every single test clause should usually have one assert statement (or a few that logically belong together, like checking both values of a pair).
  • if an assertion is not self-explanatory, add a failure message. Try to avoid that, though.
  • Always use the appropriate assert. E.g., if you check for equality, do not ASSERT_TRUE(x == y), but use ASSERT_EQ(x,y).

Related

Wiki: Main

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.