Skip to content

Latest commit

 

History

History
94 lines (76 loc) · 4.81 KB

CODING_STYLE_GUIDELINES.md

File metadata and controls

94 lines (76 loc) · 4.81 KB

Coding style and guidelines

Revision 4

This file describes the coding style and guidelines used by this repository, which must be followed for any new code.

Coding style and guidelines

Naming conventions

  • Variables, functions, methods, class members, namespaces, files: lowerCamelCase
  • Classes, structs, enum classes, enum values, aliases, constexpr, static class variables: UpperCamelCase
  • C-style defines: ALL_CAPS_WITH_UNDERSCORE_TO_SEPARATE_WORDS
  • Class member names should start with an underscore
  • Static variables should start with s_
  • When enumerating a map/unordered_map using a for loop, name the iterator loop variable somethingKV (key/value)
  • Always use the full namespace for types used to declare observer and delegate methods in public APIs, so the user overriding the methods doesn't have to type all of them manually

C-style

  • Prohibit C-style cast, use static_cast instead
  • Prohibit C-style types (int, long, char), use cstdint types instead (std::int32_t, std::int8_t)
  • Prohibit typedef keyword, use using instead
  • Prohibit C-style enums, use enum class instead

Declaration and Initialization

  • Always initialize non static data members (NSDM) except when impossible (when the data member is a reference), using brace initialization
  • Always initialize structs fields using brace initialization to prevent UB in cases like this:
// Start with a struct defined like this
struct Foo
{
	int a;
};

// Declare a variable bar of type Foo using aggregate initialization
auto const bar = Foo{5};

// At a later time, a new field is added to Foo so that it's now defined like this
struct Foo
{
	int a;
	int b;
};

// !!! The previously declared bar variable will still compile, as it is using aggregate initialization, but it will now have an unitialized field without knowing it !!!

// No such UB would have happened if Foo was defined like this
struct Foo
{
	int a{0};
	int b{0};
};
  • Always specify the type to the right of the = sign when declaring a variable (and always use the = sign for the sake of consistency). Since c++17 and [dcl.init], there is no downside to this rule.
  • Always use auto for variables declaration as it's impossible to have an uninitialized variable (possible since c++17 thanks to [dcl.init] update in P0135R1: Guaranteed copy elision)
  • Always put const to the right of the type (for consistency and prevent ambiguity when used with auto and pointers)
  • Add virtual and override keywords when overriding a virtual method for clarity and consistency
  • Always declare function parameters as const (so they cannot be changed inside the function), except for obvious reasons (references, movable objects and pointers that are mutable)
  • Always declare variables as const if they never change

Header inclusion order

  • Current library public headers (using "")
  • Current library private headers (using "")
  • Other non-standard libraries public headers (using <>)
  • Standard libraries public headers (using <>)

Separate each category with an empty line feed.

Example:

#include "la/avdecc/avdecc.hpp"

#include "entity.hpp"

#include <windows.h>
#include <boost/boost.hpp>

#include <vector>

Unsorted

clang-format

Use the provided clang-format file to correctly format the code.

clang-tidy

TBD / WIP