File: coding_guidelines.rst

package info (click to toggle)
roc-toolkit 0.4.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,684 kB
  • sloc: cpp: 102,987; ansic: 8,959; python: 6,125; sh: 942; makefile: 16; javascript: 9
file content (172 lines) | stat: -rw-r--r-- 5,512 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
Coding guidelines
*****************

.. contents:: Table of contents:
   :local:
   :depth: 1

Language and libraries
======================

The usage of C++ in this project is quite specific. The codebase is primarily written in what we refer to as "C with classes", a simplified subset of C++ that intentionally omits several of its features:

* No C++ features beyond C++98
* No exceptions
* No STL (the algorithms-and-containers part of the standard library)
* No general-purpose utility libraries like Boost
* Lightweight "core" library (roc_core) instead of STL
* Templates are mostly avoided (except utility classes in core)
* Inheritance is primarily used only for "interface inheritance"
* Overloading, operators, default arguments are avoided

The roc_core library makes several essential design choices that differ significantly from STL:

* it is small and lightweight
* heavy operations, like deep copying or allocations, are never implicit
* most operations include safety checks and will trigger a panic with stacktrace on incorrect usage
* most containers are based on intrusive data structures
* fine-grained memory management based on arenas and pools
* building blocks for lock-free programming

These design choices render Roc codebase pretty different from both plain C and modern C++ code.

This approach may not be suitable for every project, but it appears to have been effective in the case of Roc due to its low-level, real-time nature, and at the same time the considerable size of its codebase.

Portability
===========

* The code should run on a variety of operating systems, compilers, and hardware architectures, including rather old compilers and distributions. See :doc:`supported platforms </portability/supported_platforms>` page.

.. raw:: html

    <span></span>

* The code specific to platform, compiler, or optional features and dependencies, should be isolated inside corresponding :ref:`target directories <targets>`. All other code should be portable across all supported configurations.

Best practices
==============

* The code should compile without warnings. Use ``--enable-werror`` :doc:`option </building/scons_options>` to turn warnings into errors.

.. raw:: html

    <span></span>

* Cover every component with class-level unit tests if possible. Additionally, cover high-level features with pipeline-level integration tests. We use `CppUTest <https://cpputest.github.io/>`_.

.. raw:: html

    <span></span>

* Prefer RAII and smart pointers for resource management.

.. raw:: html

    <span></span>

* Prefer either non-copyable or trivial-copy objects. Avoid making "heavy" operations implicit, in particular, operations involving memory management.

.. raw:: html

    <span></span>

* Use ``const`` when it's useful.

.. raw:: html

    <span></span>

* Use anonymous namespaces instead of static globals, functions, and constants.

.. raw:: html

    <span></span>

* Use enums instead of defines, when possible.

.. raw:: html

    <span></span>

* Use arenas and pools for memory management.

.. raw:: html

    <span></span>

* Carefully log (using ``roc_log``) all important events and information needed to understand why an error occurred.

.. raw:: html

    <span></span>

* Panic (using ``roc_panic``) when a contract or an invariant is broken. A panic is always preferred over a crash or undefined behavior. However, remember that panics are only for bugs in Roc itself. Never panic on invalid or unexpected data from the outside world.

Coding style
============

* The code should be formatted using ``scons fmt``, which invokes ``clang-format``. If it goes awry, you can prevent a file from being formatted by adding it to ``.fmtignore``.

.. raw:: html

    <span></span>

* Header and source files should contain the "Roc Streaming authors" copyright and license header. Running ``scons fmt`` will automatically insert them.

.. raw:: html

    <span></span>

* Headers, classes, public members, and free functions should be documented using Doxygen. Use ``--enable-doxygen`` :doc:`option </building/scons_options>` to enable warnings about undocumented elements.

.. raw:: html

    <span></span>

* Prefer creating individual .h and .cpp files for every class. Use snake_case for file names and old-style header guards, which are automatically inserted by ``scons fmt``.

.. raw:: html

    <span></span>

* Use upper case SNAKE_CASE for macros, CamelCase for class names, and lower case snake_case for methods, functions, fields, and variables. Add trailing underscore\_ for private methods and fields.

.. raw:: html

    <span></span>

* Members in class should have the following order:

  * public members:
     * types and constants
     * methods

  * protected members:
     * types and constants
     * methods

  * private members:
     * types and constants
     * methods
     * fields

.. raw:: html

    <span></span>

* The code should be formatted according to our 1TBS-like indentation style defined in ``.clang-format`` config:

  * use 4 spaces for indentation;
  * place opening braces on the same line as the control statement;
  * use braces even for single-statement blocks;
  * don't place condition or loop bodies at the same line as the control statement.

.. raw:: html

    <span></span>

* ``#endif`` and ``#else`` statements should have trailing ``// <NAME>`` and ``// !<NAME>`` comments. Namespace closing brace should have trailing ``// namespace <name>`` comment.

.. raw:: html

    <span></span>