Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
jami-docs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
savoirfairelinux
jami-docs
Commits
9895f372
Commit
9895f372
authored
4 years ago
by
Adrien Béraud
Browse files
Options
Downloads
Patches
Plain Diff
Update Libring coding rules
parent
7ff6fe2b
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
guidelines/Libring-coding-rules.md
+2
-303
2 additions, 303 deletions
guidelines/Libring-coding-rules.md
with
2 additions
and
303 deletions
guidelines/Libring-coding-rules.md
+
2
−
303
View file @
9895f372
...
@@ -19,306 +19,5 @@ daemon).**
...
@@ -19,306 +19,5 @@ daemon).**
<!-- -->
<!-- -->
-
Rules are based on
[
Google C++
-
Rules are defined by this clang-format file:
CodingStyle
](
https://google.github.io/styleguide/cppguide.html
)
.
https://git.jami.net/savoirfairelinux/ring-daemon/blob/master/.clang-format
We've modified them for this project.
This wiki is a permanent Work-In-Progress system.
**
So not all rules are
written yet.
**
That doesn't mean we don't have them yet (we == core
developer members).
-
Some strongly recommended reading about modern C++:
-
[
ISO C++ SuperFAQ
](
https://isocpp.org/faq
)
-
[
Herb Sutter GotW
](
https://herbsutter.com/gotw/
)
------------------------------------------------------------------------
## Rules
### Language Standard
We SHALL use the
**C++17 standard**
syntax only.
For gnu-gcc and clang, use compiler command line option
`-std=c++17`
to
enforce this rule.
### Maximum Line Length
You SHOULD keep your line length under the
**120 characters limit**
.
This is mainly so that integrators can use split view to compare files,
and keeping the line width below 120 columns makes this easier, even on
wide screens. Configure your editing tools to this limit.
If this rule impacts negatively the readability or the validity of the
code, it can be transgressed. Here are a few valid
**exceptions**
to
that rule:
1.
If a comment line contains an example command or a literal URL
longer than 120 characters, that line may be longer than 120
characters for ease of cut and paste.
2.
A raw string literal may exceed 120 characters. Except for test
code, such literals should appear near the top of a file.
3.
An
\#
include statement with a long path may exceed 120 columns.
### Non-ASCII Characters
Non-ASCII characters should be rare, and MUST use
**UTF-8**
formatting.
You SHALL NOT use the C++11 char16
\_
t and char32
\_
t character types,
since they're for non-UTF-8 text. For similar reasons you also SHALL NOT
use wchar
\_
t (unless you're writing code that interacts with the Windows
API, which uses wchar
\_
t extensively).
### Spaces vs. Tabs
In code files (i.e. .cpp or .h), you SHALL use
**spaces to indent**
.
One indent level is 4 (four) consecutive spaces. You should set your
editor to emit spaces when you hit the tab key and when you save your
file.
### Header multiple-inclusion guard
All header files SHALL have
**an unique header guard**
to prevent
multiple inclusion, using
\#
ifndef xxx ...
\#
define xxx ...
\#
endif form.
The format of the symbol name may be
<FILE>
\_
H or
\_
<FILE>
\_
H
\_
, but you
MUST ensure its uniqueness.
We also support the pragma once form ONLY in non publicly exposed
headers files, as only GCC and clang are supported to build the daemon
core.
Example with the
**foo.h file**
:
```
cpp
#ifndef FOO_H #define FOO_H
...
#endif // FOO_H
```
**Notice the MANDATORY comment of the ending \#endif.**
Example with
**pragma version**
:
```
cpp
#pragma once
```
### Namespace
We're using
**Named namespace**
.
-
All symbols that are not exposed SHALL be in ring namespace.
-
All symbols that are publicly exposed SHALL be in DRing namespace.
A
**single namespace**
SHALL be written like this:
```
cpp
namespace
mynamespace
{
// Follow our namespace scoped code
class
Foo
{
(...)
};
}
// namespace mynamespace
```
+
A namespace definition block DOESN'T indent the encapsulated code.
+
The closing bracket SHALL be commented with the related namespace.
A
**nested namespace**
may be written like
this:
```
cpp
namespace
mynamespace1
{
namespace
mynamespace2
{
namespace
mynamespace3
{
// some code that belong to mynamespace1::mynamespace2::mynamespace3
}
// namespace mynamespace1::mynamespace2::mynamespace3
```
+
This single-line notation is used until C++ standard adopts the form
namespace A::B::C {
If you need to express different code in multiple namespace you may use
for example the form:
```
cpp
namespace
mynamespace1
{
namespace
mynamespace2
{
// some code that belong to mynamespace1::mynamespace2
}
// namespace mynamespace1::mynamespace2
namespace
mynamespace3
{
// some code that belong to mynamespace1::mynamespace3
}
// namespace mynamespace1::mynamespace3
}
// namespace mynamespace1
```
Namespaces wrap the entire source file after includes, gflags
definitions/declarations, and forward declarations of classes from other
namespaces.
-
You SHALL NOT use a
*using-directive*
to make all names from a
namespace available. Particullary true for the standard
library (std::)
<!-- -->
```
cpp
// Forbidden -- This pollutes the namespace.
using
namespace
foo
;
```
-
You may use a
*using-declaration*
anywhere in a .cpp file, and in
functions, methods or classes in .h files.
<!-- -->
```
cpp
// OK in .cpp files.
// But must be in a function, method or class in .h files.
using
::
foo
::
bar
;
```
### Naming
-
_General Rules_
Names SHOULD be descriptive; avoid abbreviations.
Give as descriptive a name as possible, within reason. Do not worry
about saving horizontal space as it is far more important to make your
code immediately understandable by a new reader. Do not use
abbreviations that are ambiguous or unfamiliar to readers outside your
project, and do not abbreviate by deleting letters within a word.
-
_Type Names_
Type names start with a capital letter and have a capital letter for
each new word, with no underscores: MyExcitingClass, MyExcitingEnum.
-
_Class Data Members_
All private data members of classes, both static and non-static, are
named like ordinary nonmember variables, but with a trailing underscore.
```
cpp
class
Call
{
...
private:
int
number_
;
// OK - underscore at end.
std
::
string
peerName_
;
// OK.
static
std
::
vector
<
Call
>
subCalls_
;
// OK.
};
```
### Casting
-
You SHOULD avoid C casts, prefer C++ casts (static
\_
cast,
const
\_
cast, reinterpret
\_
cast)
_Rationale:_
Both reinterpret
\_
cast and C-style casts are
dangerous, but at least reinterpret
\_
cast won't remove the const
modifier
-
It's RECOMMENDED to use brace initialization for conversion of POD
types like int{myFloat} instead of (int)myFloat
_Rationale:_
When refactoring code, the compiler will instantly let
you know if the cast would become dangerous.
Using brace initialization (
*{}*
) permits compile-time detection of
dangerous narrowing conversion, not detected with classic constructor
call (with brackets
*()*
).
### Static and Global Variables
Static or global variables of class type are FORBIDDEN: this is the
source of static initialization order fiasco.
Take a look to this library talking about the issue and trying to remove
them as possible:
<https://cryptopp.com/wiki/Static_Initialization_Order_Fiasco>
However, such variables are allowed if they are constexpr: they have no
dynamic initialization or destruction.
Objects with static storage duration, including global variables, static
variables, static class member variables, and function static variables,
must be Plain Old Data (POD): only ints, chars, floats, or pointers, or
arrays/structs of POD.
### Microsoft Compiler Compliance
Guidelines for compliance with Microsoft (R) C/C++ Optimizing Compiler
Version 19.00.23918
If alternative tokens for logical operators (
<i>
and, not, or
</i>
etc.)
are used, you must include
<ciso686>
```
cpp
// source or header file in which alternate logical operator tokens are used
#include
<ciso646>
```
Initializing (nested) structures should be complete and implicit without
the use of designators
```
cpp
struct
A
{
struct
B
{
int
ivalue
;
}
child
;
bool
bvalue
;
};
A
wrong
=
{
.
child
=
{
.
ivalue
=
1
},
.
bvalue
=
true
};
//error in MSVC
A
right
=
{
{
1
},
true
};
//OK in MSVC
A
right
=
{
true
};
//OK but will assign ivalue to true
```
## Automatic Formating
Correctly format your code using following
**astyle**
(versions
<
3.
0) command:
`astyle --indent=spaces=4 --max-code-length=120 --attach-namespaces --attach-inlines --attach-extern-c --indent-switches --indent-preproc-define --indent-col1-comments --min-conditional-indent=0 --break-blocks --keep-one-line-blocks --pad-header --unpad-paren --align-pointer=type --align-reference=type --close-templates <input-files>`
With astyle >= v3.0, we recommand to add these options too:
`--pad-oper --pad-comma`
## Future
This section is related to future features related to Coding Rules
chapter.
### CPPLINT
Google has made an automatic tool to check coding rules conformance of
C++ sources. We may use it, with modifications, to help contributors to
check their code in an automatic way, before submitting it for review.
This tool is written in Python and available from (in its origin form)
here:
<http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py>
The modified version for Ring is under development/testing and is
available in the tools directory as cpplint.py3.
You can see it online using our GitHub mirror:
<https://github.com/savoirfairelinux/ring-daemon/blob/master/tools/cpplint.py3>
### Helpers
Check all sources on ring-daemon project (adapt verbose level as
needed):
`find src bin -regex '.*\.\(cpp\|h\)' -a -not -regex '.*\.adaptor.h' | xargs cpplint.py --linelength=120 --filter=-build/header_guard --verbose=5 {}`
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment