Codestyle Guide
In general, Google's coding standard is used, and we strongly encourage to read it.
Code Style Guide
All code should conform to C++17 standard. Here's a summary of the key rules specified in the configuration:
Includes
- We use
.cpp
and.hpp
files, not.cc
and.h
(.c
and.h
are used for C code), in UTF-8 encoding. - File names are lowercase with underscores, like
sc_memory.cpp
. - Directory names are lowercase with hyphen, like
sc-memory/
. - We use
#pragma once
instead of the#define
Guard in header files. - Include categories are specified with priorities. There are two main categories: external libraries and internal libraries. External libraries have the highest priority.
- Includes are sorted and grouped by directory, there should be newlines between different directories.
- Order of directories in includes:
current_dir/current_file.hpp
, other includes from the same dir, includes from other dirs sorted by name.
#include "test.hpp"
#include <curl/curl.h>
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include "hash/hmac.h"
#include "hash/sha256.h"
#include "sc-memory/sc_event_wait.hpp"
#include "sc-memory/sc_agent.hpp"
- Don't use
using namespace std
or other namespaces globally. You can use them locally in test cpp files or functions.
Note
Unfortunately, sources of sc-kpm
does not comply these rules. But you must comply these rules!
Indentation and Spacing
- The code should use spaces for indentation. The indentation width is set to 2 spaces. The code should not use tabs.
// It is correct style.
sc_uint32 ExampleFunc()
{
if (condition)
{
// Code block
}
else
{
// Code block
}
return 0;
}
// It is incorrect style.
sc_uint32 ExampleFunc()
{
if (condition)
{
// Code block
}
else
{
// Code block
}
return 0;
}
- Spaces before the opening parenthesis in control statements.
// It is correct style.
void ExampleFunction(sc_uint32 x)
{
if (x > 0)
{
// Code block
}
for (sc_uint32 i = 0; i < x; ++i)
{
// Code block
}
while (x > 10)
{
// Code block
}
}
// It is incorrect style.
void ExampleFunction(sc_uint32 x)
{
if(x > 0)
{
// Code block
}
for(sc_uint32 i = 0; i < x; ++i)
{
// Code block
}
while(x > 10)
{
// Code block
}
}
- Spaces before the colon in constructor initializer lists.
// It is correct style.
class MyClass
{
public:
// Constructor with initializer list
MyClass(sc_uint32 x, sc_uint32 y)
: m_x(x)
, m_y(y)
{
// Constructor body
}
private:
sc_uint32 m_x; // `m` - is abbreviation of `member`
sc_uint32 m_y;
static sc_uint32 ms_maxX; // `ms` - is abbreviation of `member static`
static sc_uint32 ms_maxY;
};
- Spaces should be inserted before assignment operators and around pointer and reference qualifiers.
// It is correct style.
sc_uint32 x = 10;
sc_uint32 * ptr = &x;
sc_uint32 const * constPtr = &x;
sc_uint32 & ref = x;
// It is incorrect style.
sc_uint32 x = 10;
sc_uint32* ptr = &x;
const sc_uint32 *constPtr = &x;
sc_uint32& ref = x;
- Use right-to-left order for variables/params.
Whitespace
- Remove extra whitespaces at the end of lines.
- Spaces in empty blocks and parentheses should be omitted.
- Trailing commas should be added in wrapped situations.
Brace Style
- Braces for functions, classes, namespaces, etc., should be on a new line.
// It is correct styles.
void ExampleFunction()
{
// Code block
}
class ExampleClass
{
public:
// Class members
};
namespace exampleNamespace
{
// Namespace contents
}
// It is incorrect styles.
void ExampleFunction() {
// Code block
}
class ExampleClass {
public:
// Class members
};
namespace exampleNamespace {
// Namespace contents
}
- Empty functions, classes, and namespaces should be split into separate lines.
// It is correct style.
void ExampleFunction()
{
}
class ExampleClass
{
};
namespace exampleNamespace
{
}
- Braces for control statements always on a new line.
// It is correct style.
if (condition)
{
// Code block
}
else
{
// Code block
}
for (sc_uint32 i = 0; i < 10; ++i)
{
// Code block
}
// It is incorrect style.
- Always break after a multiline string.
// It is correct style.
std::string multilineString = "This is a long string that "
"spans multiple lines.";
- Always break functions declarations and calls.
// It is correct style.
sc_uint32 ExampleFunction(
sc_uint32 argument1,
sc_uint32 argument2,
sc_uint32 argument3,
sc_uint32 * result,
sc_uint32 * delta)
// It is incorrect style.
sc_uint32 ExampleFunction(
sc_uint32 argument1, sc_uint32 argument2, sc_uint32 argument3,
sc_uint32 * result, sc_uint32 * delta)
Line Length and Wrapping
-
The maximum column limit is set to 120 characters.
-
Break binary operators before the operator.
// It is correct style.
sc_uint32 const result = longVariableName
+ anotherLongVariableName
+ yetAnotherLongVariableName;
// It is incorrect style.
sc_uint32 const result = longVariableName +
anotherLongVariableName +
yetAnotherLongVariableName;
- Break before ternary operators.
// It is correct style.
sc_uint32 const value = condition
? trueValue
: falseValue;
// It is incorrect style.
sc_uint32 const value = condition ?
trueValue :
falseValue;
- Break before braces in custom scenarios.
// It is correct style.
if (condition)
{
// Code block
}
else
{
// Code block
}
// It is incorrect style.
if (condition) {
// Code block
}
else {
// Code block
}
- In one line
if
,for
,while
we do not use brackets. If one linefor
orwhile
is combined with one lineif
, do use brackets for cycle.
for (ScAddr const & addr : addrList)
context.EraseElement(addr);
...
for (ScAddr const & addr : addrList)
{
if (addr.IsValid())
return true;
}
Naming
C Naming
- Macros and C-style enums must be named in UPPER_CASE, and enum values must be prefixed with a capitalized enum name.
- All other objects must be named in snake_case.
C++ Naming
- Underscores are allowed only in prefixes for member variables and namespace names, like
int m_keynodeAddr; namespace sc_utils
. - We use
using
keyword instead oftypedef
. - Compile-time constants must be named in camelCase, starting with a lower-case
k
, e.g.kCompileTimeConstant
and marked asconstexpr
when possible. - Values of enum classes must be named in CamelCase, e.g.
enum class Color { Red, Green, LightBlue };
.
Comments
- Doxygen-style comments can be used.
Check code style
Most of our coding style is specified in a configuration file for ClangFormat.
To automatically format a file, install clang-format
and run:
To check all format code use script check_formatting.sh
.
Or use script format_code.sh
to reformat all code.
Tips and Hints
- Code should compile without warnings! Just deprecated warning could be present for a short time. But if you see them, then try to fix it in a separate commit.
- If you see outdated code which can be improved - DO IT NOW (but in the separate pull request).
- Your code should work at least on: Ubuntu 20.04 and 22.04; Debian 11; macOS platforms.
- Your code should compile well with the last gcc and clang.
- Try to avoid using any new 3rd party library if it is not fully tested and supported on supported platforms.
- Cover your code with unit tests.
- If you don't have enough time to make it right, leave a
// TODO(DeveloperName): need to fix it
comment and make issue on GitHub.