Skip to content

Code readability guidelines

vhirtham edited this page Jul 11, 2018 · 6 revisions

It is easier to understand code that has a good readability. The following guidelines should help to produce easily readable code. Even if it can't make complex algorithms simpler it ensures that you can at least follow the used set of instructions.

Table of Contents

  1. General
    1. Keep functions as short as possible
    2. Use blank lines as separator
    3. Typedefs for templates
  2. Specific topics
    1. Use range based for loops
    2. Use structured bindings

General

Keep functions as short as possible

If there are just a few lines, it is more likely to understand the function. Move subtasks of an algorithm to separate functions and give them a meaningful name. The compiler will most likely inline it anyways so that it won't result in a performance hit. This way a function which might contain hundreds of lines (when everything is written in place) might look like this:

Use blank lines as separator

The intention of this is basically the same as in the previous subsection. Blank lines should be used to mark the end of a set of instructions which accomplish a subtasks

void InsertIntoDataFile(char* fileName)
{
    auto file = OpenDataFile(fileName);
    auto position = FindPositionToWrite(file);
    WriteToFile(file, position);
    CloseFile(file);
}

Typedefs for templates

When declaring an instance of a template class the line of code can get messy quiet fast. In this it is be better to use a typedef or the using keyword to define a short descriptive name.

Specific topics

Use range based for loops

Always use range based for loops if there is no need to know the element number/counter.

for (const auto& element : elements)
{
    // ... do some stuff ...
}

Use structured bindings

Structured bindings are a c++17 feature which make it possible to extract multiple values from a class or array and assign them to different variables within a single line. Additionally it is not even necessary to declare those variables. Beside the obvious usecase of multiple return values it can be used in a nice fashion to simplify a range based for loop over a map (code snipped at the end of the section). Other use cases can be found here. Be careful though with using it for multiple return values. The detour over a std::tuple might cost some performance (read here).

From linked stack overflow site:

int main() 
{
    std::map<int, int> m = {{ 0, 1 }, { 2, 3 }};
    for(auto &[key, value] : m) 
        std::cout << key << ": " << value << std::endl;
}

Clone this wiki locally