Skip to content

Coding Guide

Lydia Buntrock edited this page Mar 22, 2021 · 7 revisions

Where to write the code documentation: in .cpp or in .hpp files?

  • Write short categorizing comments in the header files, to keap them relatively clean and clear. Describe the API designs and how they are used.. These comments discribe your public interface for clients. -> .hpp files.
  • Write detailed comments next to the implementation files to ensure code understanding and make changes to algorithms easier. Describe the implementation alternatives / issues and decisions in the implementation: that’s for yourself and other maintainers, even someone reviewing the design as input to some next-gen system years hence. -> .cpp files.

This is a much discussed problem. You can read more about it here (exceptionshub) and here (stackoverflow).

Doxygen Commands

https://www.doxygen.nl/manual/commands.html

Coding Style

Structs, Classes and Enums

Structs and classes should start with a capital letter.

class EnumValidator { ... }
struct AlignedSegment { ... }
enum BamFlags { ... }

Comments (for Doxygen)

We comment functions only in hpp files and keep the code in the associated cpp files. Parameter descriptions always start with a - and a lowercase letter and end without a dot.

/*! \brief Short function description.
 * 
 * /tparam something_type - description
 *
 * /param name     - description
 * /param name2    - description
 * /param namelang - description
 * /param na       - description
 * 
 * /return description
 *
 * /details A longer desctiption goes here.
 */
template <typename something_type>
out foo(name, name2, namelang, na) { ... }
  • If it is a void function, we add in and out to the parameters.
/*! \brief Short function description.
 * 
 * /param[in]      name     - description
 * /param[in]      name2    - description
 * /param[in, out] namelang - description
 * /param[in, out] na       - description
 */
void faa(const name, const name2, & namelang, & na) { ... }

Variables

We follow the seqan rules (https://github.com/seqan/seqan3/wiki/General-formatting#variable):

General:

  • for all types that are not builtin arithmetic types, use brace initialization if at all possible (not () or =
  • initialise all variables upon declaration, unless you really know what you are doing (if in doubt, initialise with empty {})
// brace-initialize, don't use =
int i{7};
int & k{i};
float f{4.5};

// assignment
i = 8;
f = 3.4;

// loops
for (size_t j = 0; j < i; ++j)
    std::cout << j << '\n';

// linebreaks and alignment for readability
// in this case add braces, even for one-line body
for (size_t j = 0;
     (j < i) && some_very_long_condition_or_call();
     ++j)
{
    std::cout << j << '\n';
}

// always balance braces
if (i < 7)
{
    i = 21; // just one line
}
else
{
   i = 9;
   f = 13.3;
}

// tiny lambda may go in one line
auto f = [] (int & i) { ++i; }; 

// long lambda must not
std::for_each(v.begin(), v.end(), [] (int & i)
{
    i += 17;
    // ...
});

const-ness:

  • when possible, make variable constexpr or const (in that order)
  • always use "east-const", i.e. put const on the right of the type that is modified; see http://slashslash.info/eastconst/ for more infos
  • if a variable is constexpr, put the constexpr on the left of the type (west-constexpr)

Global variables:

  • should be inline and constexpr
variable_type const variable_name;

inline constexpr variable_type variable_name = something;

// small function, readable
inline void my_free_function(int const i, float const f)
{
    // ...
}

Commit Style