Весь новый код должен следовать нижеследующим правилам.
Если вы делаете изменения в файле, который ещё не следует этим правилам, ваши изменения всё равно должны им следовать.
int myFunction(int a)
{
// код
}
void myFunction()
{ // пустое тело функции
}
MyClass::MyClass(int *parent)
: m_parent(parent)
{
// инициализация
}
int MyClass::myMethod(int a)
{
// код
}
class MyOtherClass
{
public:
// код
protected:
// код
private:
// код
};
namespace Name
{
// код
}
// Лямбды
[](int arg1, int arg2) -> bool { return arg1 < arg2; }
[this](int arg)
{
this->acc += arg;
}
if (condition)
{
// код
}
for (auto a = 0; a < b; ++b)
{
// код
}
switch (a)
{
case 1:
// код
break;
case 2:
// код
break;
default:
// код
}
switch (var)
{
case 1:
{
// объявление локальных переменных
// код
}
break;
case 2:
{
// объявление локальных переменных
// код
}
break;
default:
// код
}
else if
/else
должны распологаться на отдельных строках:
if (condition)
{
// код
}
else if (condition)
{
// код
}
else
{
// код
}
Блоки if с одиночными выражениями должны выглядеть так:
if (condition)
a = a + b;
Допустимое исключение: return
, break
или continue
, когда
условие не слишком длинное и занимает одну строчку. Однако даже в этом
случае можно использовать предыдущее правило.
if (a > 0) return;
while (p)
{
// ...
if (!b) continue;
}
Скобки можно опустить, если условие в if
/else
занимает одну строчку, и если
тело if
/else
состоит из одного выражения. Это же правило применимо к циклам.
Если одна из веток if - else
нуждается в скобках, вторую ветку тоже нужно обернуть в скобки.
if (a < b) // условие
do(a); // тело - одно выражение. Можно без скобок
if (a < b)
do(a);
else if (a > b)
do(b);
else
do(c);
if (a < b)
{
do(a);
}
else if (a > b)
{ // здесь нужны скобки, поэтому все остальные ветки тоже в скобках
do(b);
do(d);
}
else
{
do(c);
}
Это не функции. Пробелы внутри скобок не нужны. Пробел перед скобками - нужен:
MyType obj {}; // пустой инициализатор
MyType obj {expr};
MyType obj {expr1, /*...,*/ exprN};
Для отступов использовать табуляцию, для выравнивания - пробелы (ссылка):
void my_func(void)
{
>---do_something();
>---if (everything_ok()){
>--->---int var1.........= 0,
>--->---....another_var..= 1,
>--->---....third_var....= 2;
>--->---do_something_different();
>---}
}
Кодировка файлов: UTF-8 Переводы строк: unix (LF).
Списки инициализации должны быть вертикальными. Это даёт более читабельные diff-ы. Двоеточие в списке инициализации должно быть с отступом и располагаться в строке перед первым элементом. Запятые - перед каждым следующим элементом (тоже с отступом).
myClass::myClass(int a, int b, int c, int d)
: m_a(a)
, m_b(b)
, m_c(c)
, m_d(d)
{
// код
}
Enum-ы должны быть вертикальными. Это даёт более читабельные diff-ы.
enum Days
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
Имена должны быть в camelCase.
Имена типов и пространств имён должны начинаться с заглавной буквы.
class ClassName {};
struct StructName {};
enum EnumName {};
using SomeList = List ;
namespace NamespaceName
{
}
Имена переменных должны начинаться со маленькой буквы.
int myVar;
Имена приватных переменных-членов класса начинаются с маленькой буквы и должны иметь префикс m_
.
class MyClass
{
int m_myVar;
}
Заголовочные файлы должны включаться в следующем порядке:
- Системные заголовочные файлы;
- Заголовочные файлы стандартной библиотеки C/C++
- Заголовочный файл модуля
- Заголовочные файлы проекта
Заголовки внутри каждой группы должны распологаться в алфавитном порядке.
Если какой-то заголовочный файл включается условно, то его помещать в конце группы.
Пример:
// file: MyModule.cpp
// Системные заголовочные файлы
#include <intrinsics.h>
// Заголовочные файлы стандартной библиотеки C/C++
#include <cstdint>
#include <cstdio>
// Заголовочный файл модуля
#include "MyModule.h"
// Заголовочные файлы проекта
#include "MyAnotherModule.h"
Вместо "include guard" можно использовать #pragma once
:
// example_module.h
#pragma once
#include
class ExampleModule : public BaseModule
{
// (some code omitted)
};
-
Разбиение длинных строк:
-
Пробелы в выражениях
// До и после оператора присваивания и другого бинарного или тернарного оператора нужны пробелы. Не нужны пробелы между операторами инкремента/декремента и их операндами.
a += 20;
a = (b <= maxVal ? b : maxVal);
++a;
--b;
for (int a = 0; a < b; ++b)
{
}
// Цикл по диапазону, пробелы перед и после двоеточия
for (auto i : container)
{
}
// Наследование, пробелы до и после двоеточия
class Derived : public Base
{
};
- Предпочитать пре-декремент/инкремент пост-инкременту/декременту
++i, --j; // Так лучше
i++, j--; // Так только при необходимости
- Первая строка (заголовок сообщения коммита) - краткое описание коммита. Длина до 80 символов. Краткое описание не должно содержать лишних деталей;
- Затем пустая строка (в GUI обычно формируется автоматически);
- Затем более подробное описание (тело сообщения коммита), если это необходимо.
- В теле сообщения коммита описать, что делает коммит и зачем.
- Если коммит закрывает какую-то задачу, нужно указать это в теле коммита (
закрывает задачу #123
)