2014-11-16 23:25:50 +08:00
All new code must follow the following coding guidelines.
If you make changes in a file that still uses another coding style, make sure that you follow these guidelines for your changes instead.
2016-01-10 20:56:53 +08:00
**Note 1:** I will not take your head if you forget and use another style. However, most probably the request will be delayed until you fix your coding style.
**Note 2:** You can use the `uncrustify` program/tool to clean up any source file. Use it with the `uncrustify.cfg` configuration file found in the root folder.
**Note 3:** There is also a style for QtCreator but it doesn't cover all cases. In QtCreator `Tools->Options...->C++->Code Style->Import...` and choose the `codingStyleQtCreator.xml` file found in the root folder.
2014-11-16 23:25:50 +08:00
### 1. Curly braces ###
#### a. Function blocks, class/struct definitions, namespaces ####
```c++
int myFunction(int a)
{
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
2015-11-21 16:25:14 +08:00
void myFunction() {} // empty body
MyClass::MyClass(int *parent)
2014-11-26 21:10:43 +08:00
: m_parent(parent)
2014-11-16 23:25:50 +08:00
{
2017-09-04 23:55:37 +08:00
// initialize
2014-11-16 23:25:50 +08:00
}
2015-11-21 16:25:14 +08:00
int MyClass::myMethod(int a)
2014-11-16 23:25:50 +08:00
{
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
2015-11-21 16:25:14 +08:00
class MyOtherClass
2014-11-16 23:25:50 +08:00
{
public:
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
protected:
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
private:
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
};
2015-11-21 16:25:14 +08:00
namespace Name
2014-11-16 23:25:50 +08:00
{
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
2015-11-21 16:25:14 +08:00
// Lambdas
[](int arg1, int arg2) -> bool { return arg1 < arg2 ; }
[this ](int arg )
{
this->acc += arg;
}
2014-11-16 23:25:50 +08:00
```
#### b. Other code blocks ####
```c++
if (condition) {
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
2015-01-14 03:30:12 +08:00
for (int a = 0; a < b ; + + b ) {
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
2015-01-14 03:30:12 +08:00
switch (a) {
2014-11-16 23:25:50 +08:00
case 1:
2017-09-04 23:55:37 +08:00
// blah
2014-11-16 23:25:50 +08:00
case 2:
2017-09-04 23:55:37 +08:00
// blah
2014-11-16 23:25:50 +08:00
default:
2017-09-04 23:55:37 +08:00
// blah
2014-11-16 23:25:50 +08:00
}
```
#### c. Blocks in switch's case labels ####
```c++
2015-01-14 03:30:12 +08:00
switch (var) {
2014-11-16 23:25:50 +08:00
case 1: {
2017-09-04 23:55:37 +08:00
// declare local variables
// code
2015-01-14 03:30:12 +08:00
}
break;
case 2: {
2017-09-04 23:55:37 +08:00
// declare local variables
// code
2015-01-14 03:30:12 +08:00
}
break;
2014-11-16 23:25:50 +08:00
default:
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
```
2016-04-06 03:47:05 +08:00
#### d. Brace enclosed initializers ####
Unlike single-line functions, you must not insert spaces between the brackets and concluded expressions.< br / >
But you must insert a space between the variable name and initializer.
2015-11-21 16:25:14 +08:00
```c++
2016-04-06 03:47:05 +08:00
Class obj {}; // empty
Class obj {expr};
Class obj {expr1, /*...,*/ exprN};
QVariantMap map {{"key1", 5}, {"key2", 10}};
2015-11-21 16:25:14 +08:00
```
2014-11-16 23:25:50 +08:00
### 2. If blocks ###
#### a. Multiple tests ####
```c++
if (condition) {
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
else if (condition) {
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
else {
2017-09-04 23:55:37 +08:00
// code
2014-11-16 23:25:50 +08:00
}
```
The `else if` /`else` must be on their own lines.
#### b. Single statement if blocks ####
**Most** single statement if blocks should look like this:
```c++
if (condition)
2015-01-14 03:30:12 +08:00
a = a + b;
2014-11-16 23:25:50 +08:00
```
2015-01-14 03:30:12 +08:00
One acceptable exception to this **can be** `return` , `break` or `continue` statements, provided that the test condition isn't very long. However you can choose to use the first rule instead.
2014-11-16 23:25:50 +08:00
```c++
a = myFunction();
2015-01-14 03:30:12 +08:00
b = a * 1500;
2014-11-16 23:25:50 +08:00
2015-01-14 03:30:12 +08:00
if (b > 0) return;
c = 100 / b;
2014-11-16 23:25:50 +08:00
```
#### c. Using curly braces for single statement if blocks ####
However, there are cases where curly braces for single statement if blocks **should** be used.
* If some branch needs braces then all others should use them. Unless you have multiple `else if` in a row and the one needing the braces is only for a very small sub-block of code.
* Another exception would be when we have nested if blocks or generally multiple levels of code that affect code readability.
Generally it will depend on the particular piece of code and would be determined on how readable that piece of code is. **If in doubt** always use braces if one of the above exceptions applies.
2017-03-22 22:49:19 +08:00
### 3. Indentation ###
2014-11-16 23:25:50 +08:00
4 spaces.
2017-03-22 22:49:19 +08:00
### 4. File encoding and line endings. ###
2014-11-16 23:25:50 +08:00
2015-05-04 07:09:30 +08:00
UTF-8 and Unix-like line ending (LF). Unless some platform specific files need other encodings/line endings.
2014-11-16 23:25:50 +08:00
2017-03-22 22:49:19 +08:00
### 5. Initialization lists. ###
2015-05-04 07:09:30 +08:00
Initialization lists should be vertical. This will allow for more easily readable diffs. The initialization colon should be indented and in its own line along with first argument. The rest of the arguments should be indented too and have the comma prepended.
2014-11-26 21:10:43 +08:00
```c++
myClass::myClass(int a, int b, int c, int d)
2015-11-21 16:25:14 +08:00
: m_a(a)
, m_b(b)
, m_c(c)
, m_d(d)
2014-11-26 21:10:43 +08:00
{
2017-09-04 23:55:37 +08:00
// code
2014-11-26 21:10:43 +08:00
}
```
2017-03-22 22:49:19 +08:00
### 6. Enums. ###
2014-11-26 21:10:43 +08:00
Enums should be vertical. This will allow for more easily readable diffs. The members should be indented.
```c++
2015-11-21 16:25:14 +08:00
enum Days
2014-11-26 21:10:43 +08:00
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
```
2017-03-22 22:49:19 +08:00
### 7. Names. ###
2015-11-21 16:25:14 +08:00
All names should be camelCased.
#### a. Type names and namespaces ####
Type names and namespaces start with Upper case letter (except POD types).
```c++
2016-04-06 03:47:05 +08:00
class ClassName {};
2015-11-21 16:25:14 +08:00
2016-04-06 03:47:05 +08:00
struct StructName {};
2015-11-21 16:25:14 +08:00
2016-04-06 03:47:05 +08:00
enum EnumName {};
2015-11-21 16:25:14 +08:00
typedef QList< ClassName > SomeList;
namespace NamespaceName
{
}
```
#### b. Variable names ####
Variable names start with lower case letter.
```c++
int myVar;
```
#### c. Private member variable names ####
Private member variable names start with lower case letter and should have ```m_``` prefix.
```c++
class MyClass
{
int m_myVar;
}
```
2017-03-22 22:49:19 +08:00
### 8. Header inclusion order. ###
2016-04-18 22:52:07 +08:00
The headers should be placed in the following order:
1. Module header (in .cpp)
2. System/Qt/Boost etc. headers (splitted in subcategories if you have many).
3. Application headers, starting from *Base* headers.
The headers should be ordered alphabetically within each group (subgroup).< br / >
< br / >
Example:
```c++
// examplewidget.cpp
#include "examplewidget.h"
#include <cmath>
#include <cstdio>
#include <QDateTime>
#include <QList>
#include <QString>
#include <QUrl>
#include <libtorrent/version.hpp>
#include "base/bittorrent/infohash.h"
2017-09-04 23:55:37 +08:00
#include "base/bittorrent/session.h"
2016-04-18 22:52:07 +08:00
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "ui_examplewidget.h"
```
2018-01-20 17:10:21 +08:00
### 9. Include guard. ###
`#pragma once` should be used instead of "include guard" in new code:
```c++
// examplewidget.h
#pragma once
#include <QWidget>
class ExampleWidget : public QWidget
{
// (some code omitted)
};
```
### 10. Misc. ###
2014-11-16 23:25:50 +08:00
* Line breaks for long lines with operation:
```c++
a += "b"
+ "c"
+ "d";
```
2016-03-16 01:33:35 +08:00
* **auto** keyword
2016-04-06 03:47:05 +08:00
We allow the use of the **auto** keyword only where it is strictly necessary
(for example, to declare a lambda object, etc.), or where it **enhances** the readability of the code.
Declarations for which one can gather enough information about the object interface (type) from its name
or the usage pattern (an iterator or a loop variable are good examples of clear patterns)
or the right part of the expression nicely fit here.< br / >
< br / >
When weighing whether to use an auto-typed variable please think about potential reviewers of your code,
who will read it as a plain diff (on github.com, for instance). Please make sure that such reviewers can
understand the code completely and without excessive effort.< br / >
< br / >
2016-03-16 01:33:35 +08:00
Some valid use cases:
```c++
template < typename List >
void doSomethingWithList(const List & list)
{
foreach (const auto & item, list) {
// we don't know item type here so we use 'auto' keyword
// do something with item
}
}
for (auto it = container.begin(), end = container.end(); it != end; ++it) {
// we don't need to know the exact iterator type,
// because all iterators have the same interface
}
auto spinBox = static_cast< QSpinBox * > (sender());
// we know the variable type based on the right-hand expression
```
2017-09-04 23:55:37 +08:00
* Notice the spaces in the following specific situations:
2014-11-16 23:25:50 +08:00
```c++
2017-09-04 23:55:37 +08:00
// Before and after the assignment and other binary (and ternary) operators there should be a space
// There should not be a space between increment/decrement and its operand
2016-04-06 03:47:05 +08:00
a += 20;
a = (b < = MAX_B ? b : MAX_B);
++a;
2017-09-04 23:55:37 +08:00
--b;
2016-04-06 03:47:05 +08:00
for (int a = 0; a < b ; + + b ) {
2014-11-16 23:25:50 +08:00
}
2017-09-04 23:55:37 +08:00
// Range-based for loop, spaces before and after the colon
for (auto i : container) {
}
// Derived class, spaces before and after the colon
class Derived : public Base
{
};
```
* Prefer pre-increment, pre-decrement operators
```c++
++i, --j; // Yes
i++, j--; // No
2014-11-16 23:25:50 +08:00
```
* private/public/protected must not be indented
* Preprocessor commands must go at line start
* Method definitions aren't allowed in header files
2018-02-07 23:09:48 +08:00
### 10. Git commit message ###
1. Limit the subject line to 50 characters. Subject should contain only the very essence of the changes (you should avoid extra details and internals)
2. Separate subject from body with a blank line
3. Capitalize the subject line
4. Do not end the subject line with a period
5. Use the imperative mood in the subject line (it's like you're ordering the program to do something (e.g. "Don't create temporary substrings")
6. Wrap the body at 72 characters
7. Use the body to explain what and why vs. how
8. If commit fixes a reported issue, mention it in the message body (e.g. `Closes #4134.` )
### 11. Not covered above ###
2017-03-22 22:49:19 +08:00
If something isn't covered above, just follow the same style the file you are editing has. If that particular detail isn't present in the file you are editing, then use whatever the rest of the project uses.