annotate STYLE.md @ 19:3b6c3405b9f3

Add some files in .hgignore and document it
author David Demelier <markand@malikania.fr>
date Fri, 20 Oct 2017 11:52:55 +0200
parents 314e8bb2659a
children 9573e6c9ac97
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17
314e8bb2659a Rename STYLE_CPP.md to STYLE.md
David Demelier <markand@malikania.fr>
parents: 16
diff changeset
1 PROJECT NAME CODING STYLE
314e8bb2659a Rename STYLE_CPP.md to STYLE.md
David Demelier <markand@malikania.fr>
parents: 16
diff changeset
2 =========================
314e8bb2659a Rename STYLE_CPP.md to STYLE.md
David Demelier <markand@malikania.fr>
parents: 16
diff changeset
3
314e8bb2659a Rename STYLE_CPP.md to STYLE.md
David Demelier <markand@malikania.fr>
parents: 16
diff changeset
4 C++
314e8bb2659a Rename STYLE_CPP.md to STYLE.md
David Demelier <markand@malikania.fr>
parents: 16
diff changeset
5 ===
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 Style
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 -----
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 - Always use 4 spaces as indentation,
9
ee0ef058cb94 Add note about UTF-8 / LF
David Demelier <markand@malikania.fr>
parents: 8
diff changeset
11 - Use UTF-8 charset,
ee0ef058cb94 Add note about UTF-8 / LF
David Demelier <markand@malikania.fr>
parents: 8
diff changeset
12 - Use Unix line endings,
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 - Do not exceed 120 characters for lines of code,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 - Do not exceed 80 characters for comments,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 - Never write two blank consecutives blank lines,
7
4fcd920b1a02 Add note about bad words
David Demelier <markand@malikania.fr>
parents: 6
diff changeset
16 - Do not use bad words.
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18 ### Braces
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
19
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 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
21 function definitions.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
10
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
23 Do not put braces for single line statements except for clarity.
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 if (condition) {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 apply();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 add();
10
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
28 } else
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 ok();
10
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
30
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
31 if (condition)
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
32 validate();
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
33
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
34 if (foo) {
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
35 state = long + conditional + that + requires + several + lines +
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
36 to + complete;
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
38
10
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
39 Functions require braces on their own lines.
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
40
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
41 void function()
eaae1fcabca8 Update braces style
David Demelier <markand@malikania.fr>
parents: 9
diff changeset
42 {
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
44
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 And a lambda has its braces on the same lines too:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46
13
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
47 sort([&] (auto&) {
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 return true;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 });
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 ### Spaces
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 its argument.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 Normal function calls do not require it.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
11
e4fd9e7bf69a Remove braces
David Demelier <markand@malikania.fr>
parents: 10
diff changeset
58 if (foo)
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 destroy(sizeof (int));
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 ### References and pointers
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
62
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 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
64
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 T& get(const std::string& name);
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
66
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 int* p = &x;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 ### Naming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 - English names,
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
72 - Member variables have trailing underscore (e.g foo\_bar\_),
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 - No hungarian notation.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
74
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 Everything is in `underscore_case` except template parameters and macros.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 #if defined(FOO)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 # include <foo.hpp>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 #endif
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 namespace baz {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 class object {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 private:
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
85 std::string name_;
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 inline const std::string& name() const noexcept
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 {
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
90 return name_;
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 template <typename Archive>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 void open(const Archive& ar)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 bool is_valid = false;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 } // !baz
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 ### Header guards
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 Do not use `#pragma once`.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 Header guards are usually named **PROJECT_COMPONENT_FILENAME_HPP**.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 #ifndef FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 #define FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
110
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 #endif // !FOO_COMMON_UTIL_HPP
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 ### Enums
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 Enumerations constants are always defined in separate line to allow commenting
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 them as doxygen.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 Enum class are encouraged.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 enum class color {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 blue,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 red,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 green
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125
16
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
126 ### Switch
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
127
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
128 In a switch case statement, you **must** not declare variables and not indent
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
129 cases.
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
130
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
131 switch (variable) {
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
132 case foo:
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
133 do_some_stuff();
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
134 break;
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
135 default:
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
136 break;
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
137 }
780c138ab41d Add a note about switch
David Demelier <markand@malikania.fr>
parents: 14
diff changeset
138
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 ### Files
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
140
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 - Use `.cpp` and `.hpp` as file extensions,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 - Filenames are all lowercase.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 ### Comments
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 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
147 like this. However any public function in the .hpp **must** be documented as
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 doxygen without exception.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 /*
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 * Multi line comments look like
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 * this.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 */
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 // Short comment
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
2
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
157 Use `#if 0` to comment blocks of code.
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
158
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
159 #if 0
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
160 broken_stuff();
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
161 #endif
1e34b51d9c52 Add note about if 0
David Demelier <markand@malikania.fr>
parents: 1
diff changeset
162
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 ### Includes
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 The includes should always come in the following order.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 1. C++ headers
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 2. C header
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 3. Third party libraries
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 4. Application headers in ""
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 #include <cstring>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 #include <cerrno>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 #include <sys/stat.h>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 #include <libircclient.h>
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 #include "foo.h"
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 **Note**: always use C++ headers for C equivalent, stdio.h -> cstdio, etc.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 ### Commit messages
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 Commit messages are written using the following syntax:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
186
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 Topic: short message less than 80 characters
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
188
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 Optional additional description if needed.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 Replace `Topic` with one of the following:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 - **CMake**: for the build system,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 - **Docs**: for the documentation,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 - **Misc**: for miscellaneous files,
3
David Demelier <markand@malikania.fr>
parents: 2
diff changeset
196 - **Tests**: for the unit tests.
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 Programming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 -----------
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 ### C language
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 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
204 can be rewritten in modern C++.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
205
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 ### RTTI
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 form.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
210
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 ### Arguments
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 It is recommended to pass parameters by value or const reference. Usage of
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 non-const reference as output parameter is **discouraged** and should be avoided
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 in many case because it does not allow chaining of expressions like:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 std::cout << reverse(upper(clean(" hello world! "))) << std::endl;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 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
220 is better to take it by value and modify it directly.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 std::string clean(std::string input)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 {
11
e4fd9e7bf69a Remove braces
David Demelier <markand@malikania.fr>
parents: 10
diff changeset
224 if (!input.empty() && input.back() == '\r')
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 input.pop_back();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
226
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 return input;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 Never pass primitive types as const value.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
231
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 ### Assertions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 Use the `assert` macro from the cassert header file to verify programming
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 errors.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 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
238 between the bounds of an array:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 T& operator[](unsigned index)
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 {
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
242 assert(index < length_);
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
243
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
244 return data_[index];
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 }
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 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
248 must not be written that way:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 assert(listen(10));
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 ### Exceptions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 You must use exceptions to indicate an error that was unexpected such as:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
255
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 - Failing to open a file,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 - I/O unexpected errors,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 - Parsing errors,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 - User errors.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 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
262 you need to carry more data within your exception, you should derive from
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 `std::exception`.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264
14
55bb3689093f Add chapter about error codes
David Demelier <markand@malikania.fr>
parents: 13
diff changeset
265 ### Error code
55bb3689093f Add chapter about error codes
David Demelier <markand@malikania.fr>
parents: 13
diff changeset
266
55bb3689093f Add chapter about error codes
David Demelier <markand@malikania.fr>
parents: 13
diff changeset
267 You should not use error codes to indicate errors, instead use exceptions.
55bb3689093f Add chapter about error codes
David Demelier <markand@malikania.fr>
parents: 13
diff changeset
268 Error codes are allowed in Boost.Asio though.
55bb3689093f Add chapter about error codes
David Demelier <markand@malikania.fr>
parents: 13
diff changeset
269
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 ### Free functions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 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
273 as a static member function, we're doing C++ not Java.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
274
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 Example:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 namespace util {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 std::string clean(std::string input);
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 } // !util
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
282
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 ### Variables initialization
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 Use parentheses to initialize non primitive types:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 throw std::runtime_error("foo");
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
288
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 my_class obj("bar");
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
290
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 Use brace initialization when you want to use an initializer list, type
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 elision:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 std::vector<int> v{1, 2, 3};
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 foo({1, 2}); // type deduced
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 return { "true", false }; // std::pair returned
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 Use the assignment for primitive types:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
301
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 int x = 123;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 bool is_valid = true;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 ### Classes
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 Classes are usually defined in the following order:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
308
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 1. Public inner types (enums, classes),
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 2. Protected/private members
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 3. Public functions
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
312
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 class foo {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 enum class type {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 a,
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 b
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 private:
8
d7cbb9a40f0d Member variables are now named like_this_
David Demelier <markand@malikania.fr>
parents: 7
diff changeset
321 int member_{0};
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 public:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 void some_function();
12
ba9d0618d0ff Add semicolon
David Demelier <markand@malikania.fr>
parents: 11
diff changeset
325 };
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
326
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 ### Structs
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
328
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 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
330 pack some data, just use `class` and make all fields public.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
331
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 class point {
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 public:
6
41dac98beeb2 Use inclass initializers
David Demelier <markand@malikania.fr>
parents: 3
diff changeset
334 int x{0};
41dac98beeb2 Use inclass initializers
David Demelier <markand@malikania.fr>
parents: 3
diff changeset
335 int y{0};
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 };
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
337
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 ### Return
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
339
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 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
341 more linear and not highly indented.
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
342
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 This code is preferred:
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
344
11
e4fd9e7bf69a Remove braces
David Demelier <markand@malikania.fr>
parents: 10
diff changeset
345 if (a_condition_is_not_valid)
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
346 return nullptr;
11
e4fd9e7bf69a Remove braces
David Demelier <markand@malikania.fr>
parents: 10
diff changeset
347 if (an_other_condition)
0
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 return nullptr;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
349
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 auto x = std::make_shared<object>();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
351
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 x->start();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 x->save();
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
354
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 return x;
a8462a503697 Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
356
1
9bf9b4634339 Update return statement
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
357 Additional rules:
9bf9b4634339 Update return statement
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
358
9bf9b4634339 Update return statement
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
359 - Do never put parentheses between the returned value,
9bf9b4634339 Update return statement
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
360 - Do not put a else branch after a return.
13
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
361
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
362 ### Auto
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
363
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
364 We encorage usage of `auto`, it reduces code maintainance as you don't need to
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
365 change your code when your rename types.
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
366
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
367 ````cpp
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
368 auto it = std::find_if(v.begin(), v.end(), [&] (const auto& obj) {
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
369 return obj.key() == "foo";
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
370 });
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
371
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
372 for (const auto& pair : a_map)
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
373 std::cout << pair.first << " = " << pair.second << std::endl;
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
374 ````
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
375
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
376 But do not use `auto` to write code like in python, this is not acceptable:
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
377
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
378 ````cpp
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
379 auto o = my_object("foo");
4d6bf8b3446d Add chapter about auto
David Demelier <markand@malikania.fr>
parents: 12
diff changeset
380 ````