Skip to content

Code style

Oleg Derevenetz edited this page Aug 10, 2021 · 6 revisions

Each pull request goes through code style formatting check (Code style check job in GitHub Actions) to make sure that suggested code is up to our coding standards. In any case we don't strictly enforce to follow coding rules in some situations :)

We use Clang format coding style. Please refer to clang-format file for more information.

Not every code style check could be performed by the above described tool. This is a description covering the rest of coding standard. Please note that project's code base contains a lot of old code which is not followed by this standard:

Naming

  • classes and structures are named in CamelCase style.
  • members of structures must be named in camelCase starting from lower character.
  • members of class must be named in _camelCase starting from '_' following by a lower character.
  • public methods must be named in camelCase starting from lower character.
  • protected and private methods must be named in _camelCase starting from '_' following by a lower character.
  • global and static functions and variables are named in camelCase starting from lower character. All variables and functions outside classes and structures must be put within a namespace.
namespace
{
    const std::string planetName("Earth");

    bool isCodeTrusted()
    {
        return true;
    }
}

class BlackMarket
{
public:
    BlackMarket();

    ~BlackMarket();

    bool isOpen() const;

private:
    size_t _availableTraders;

    void _precalculateRatio();
};

struct Phone
{
    uint64_t price;

    bool secondHand;
};

auto

auto word could be used with extreme caution because an invalid utilization of it could lead to implicit memory copies of objects and degrades code readability. auto could be used in cases of iterator replacements or in individual cases of range loops.

struct MonsterInfo
{
    std::string name;

    int attack;
    ...
};

...

const std::vector<MonsterInfo>& getMonsterInfos() const;

...
int totalAttack = 0;
for ( auto monsterInfo : getMonsterInfos() ) {
    totalAttack += monsterInfo.attack;
}

In the above example the loop makes a copy of each of MonsterInfo structure leading to hidden memory usage and decreasing the performance of the application. However, having modification of this loop prevents extra memory usage:

for ( const MonsterInfo & monsterInfo : getMonsterInfos() ) {
    totalAttack += monsterInfo.attack;
}

Another example:

std::vector<uint8_t> pixels;

uint8_t pixelMask = 0;
for (const auto & pixel : pixels ) {
    pixelSum |= pixel;
}

In this example const and reference are used but in fact we use extra memory as the size of reference is 32 / 64 bit while uint8_t is just 8 bit. Using a base type prevents extra memory usage:

for ( const uint8_t pixel : pixels ) {
    pixelSum |= pixel;
}

tuple

std::tuple is not recommended to be used. Please create a custom structures with readable member names.

const

  • every method which does not modify members must be qualified as const
  • every variable which is not modified in the code must be set as const

Default argument values

Try to avoid default argument values in functions and methods as it might be difficult to maintain the code in the future.