STYLE_CPP.md

Tue, 31 Jan 2017 21:51:25 +0100

author
David Demelier <markand@malikania.fr>
date
Tue, 31 Jan 2017 21:51:25 +0100
changeset 0
a8462a503697
child 1
9bf9b4634339
permissions
-rw-r--r--

Initial import

0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 PROJECT NAME C++ CODING STYLE
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 =============================
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
3
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 Style
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 -----
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 - Always use 4 spaces as indentation,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 - Do not exceed 120 characters for lines of code,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 - Do not exceed 80 characters for comments,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 - Never write two blank consecutives blank lines,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
11
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 ### Braces
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 Braces follow the K&R style, they are never placed on their own lines except for
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 function definitions.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
16
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 In addition to the K&R style, they are required everywhere even if a block
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18 contains only one statement.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
19
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 if (condition) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 apply();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 add();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 } else {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 ok();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 if (condition) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 validate();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 And a lambda has its braces on the same lines too:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
32
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 sort([&] (object&) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 return true;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 });
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 ### Spaces
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
38
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 its argument.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
41
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 Normal function calls do not require it.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
43
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 if (foo) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 destroy(sizeof (int));
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
47
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 ### References and pointers
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 References and pointers are always next to the type name and not the variable.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 T& get(const std::string& name);
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 int* p = &x;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 ### Naming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 - English names,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 - Member variables starts with `m_`,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 - No hungarian notation.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 Everything is in `underscore_case` except template parameters and macros.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
63
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 #if defined(FOO)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 # include <foo.hpp>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 #endif
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 namespace baz {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
69
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 class object {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 private:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 std::string m_name;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 inline const std::string& name() const noexcept
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 return m_name;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 template <typename Archive>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 void open(const Archive& ar)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 bool is_valid = false;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 } // !baz
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
88
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 ### Header guards
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 Do not use `#pragma once`.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 Header guards are usually named **PROJECT_COMPONENT_FILENAME_HPP**.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 #ifndef FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 #define FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 #endif // !FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 ### Enums
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 Enumerations constants are always defined in separate line to allow commenting
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 them as doxygen.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 Enum class are encouraged.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 enum class color {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 blue,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 red,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 green
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 ### Files
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 - Use `.cpp` and `.hpp` as file extensions,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 - Filenames are all lowercase.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 ### Comments
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 Avoid useless comments in source files. Comment complex things or why it is done
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 like this. However any public function in the .hpp **must** be documented as
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 doxygen without exception.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 /*
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 * Multi line comments look like
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 * this.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 */
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 // Short comment
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 ### Includes
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 The includes should always come in the following order.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
134
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 1. C++ headers
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 2. C header
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 3. Third party libraries
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 4. Application headers in ""
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
139
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 #include <cstring>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 #include <cerrno>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 #include <sys/stat.h>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 #include <libircclient.h>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 #include "foo.h"
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 **Note**: always use C++ headers for C equivalent, stdio.h -> cstdio, etc.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 ### Commit messages
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 Commit messages are written using the following syntax:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 Topic: short message less than 80 characters
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 Optional additional description if needed.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
158
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 Replace `Topic` with one of the following:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 - **CMake**: for the build system,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 - **Docs**: for the documentation,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 - **Misc**: for miscellaneous files,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 - **Tests**: for the unit tests,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 Programming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 -----------
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
168
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 ### C language
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 Do not use old C stuff like `void *`, `srand/rand`, `printf` or anything that
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 can be rewritten in modern C++.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 ### RTTI
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 form.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 ### Arguments
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 It is recommended to pass parameters by value or const reference. Usage of
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 non-const reference as output parameter is **discouraged** and should be avoided
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 in many case because it does not allow chaining of expressions like:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 std::cout << reverse(upper(clean(" hello world! "))) << std::endl;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
186
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 If your function is designed to return a modified value passed as argument, it
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 is better to take it by value and modify it directly.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 std::string clean(std::string input)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 if (!input.empty() && input.back() == '\r') {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 input.pop_back();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 return input;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 Never pass primitive types as const value.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 ### Assertions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 Use the `assert` macro from the cassert header file to verify programming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 errors.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
205
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 For example, you may use `assert` to verify that the developer access the data
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 between the bounds of an array:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 T& operator[](unsigned index)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 assert(index < m_length);
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 return m_data[index];
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 The `assert` macro is not meant to check that a function succeeded, this code
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 must not be written that way:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 assert(listen(10));
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
220
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 ### Exceptions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
222
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 You must use exceptions to indicate an error that was unexpected such as:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
224
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 - Failing to open a file,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 - I/O unexpected errors,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 - Parsing errors,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 - User errors.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 You may use the C++ standard exceptions defined in the stdexcept header but if
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 you need to carry more data within your exception, you should derive from
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 `std::exception`.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 ### Free functions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 Basic utility functions should be defined in a namespace as a free function not
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 as a static member function, we're doing C++ not Java.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
238
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 Example:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 namespace util {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
242
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 std::string clean(std::string input);
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
244
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 } // !util
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 ### Variables initialization
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
248
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 Use parentheses to initialize non primitive types:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
250
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 throw std::runtime_error("foo");
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 my_class obj("bar");
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 Use brace initialization when you want to use an initializer list, type
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 elision:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 std::vector<int> v{1, 2, 3};
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
259
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 foo({1, 2}); // type deduced
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 return { "true", false }; // std::pair returned
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 Use the assignment for primitive types:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 int x = 123;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 bool is_valid = true;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
268
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 ### Classes
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 Classes are usually defined in the following order:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 1. Public inner types (enums, classes),
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 2. Protected/private members
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 3. Public functions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 class foo {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 enum class type {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 a,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 b
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 private:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 int m_member{0};
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 void some_function();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
290
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 ### Structs
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 Do not use C structs unless you have very good reason to do so. If you want to
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 pack some data, just use `class` and make all fields public.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 class point {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 int x;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 int y;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
301
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 ### Return
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
303
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 The preferred style is to return early in case of errors. That makes the code
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 more linear and not highly indented.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 This code is preferred:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
308
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 if (a_condition_is_not_valid) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 return nullptr;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 } else if (an_other_condition) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 return nullptr;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 auto x = std::make_shared<object>();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 x->start();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 x->save();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 return x;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
321
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 Do never put parentheses between the returned value.

mercurial