comparison STYLE.md @ 773:8c44bbcbbab9

Misc: style, cleanup and update
author David Demelier <markand@malikania.fr>
date Fri, 26 Oct 2018 13:01:00 +0200
parents b452f5ce799c
children 201ddc487807
comparison
equal deleted inserted replaced
772:f5ccf65ae929 773:8c44bbcbbab9
1 irccd CODING STYLE 1 IRC Client Daemon CODING STYLE
2 ================== 2 ==============================
3
4 File content
5 ============
6
7 - Use UTF-8 charset,
8 - Use Unix line endings,
9 - Never write two blank consecutives blank lines.
10
11 Indent
12 ======
13
14 Use tabs to indent and spaces for alignment. Tabs are meant and designed for
15 indenting code and have the advantage of being configurable. On the other hand
16 to keep code clean, you must align content with spaces only *within* a line.
17
18 Note: we recommend 8 columns to avoid high number of indentations.
19
20 Example (show whitespace in your editor)
21
22 ```cpp
23 class foo {
24 public:
25 enum type {
26 dummy_value, // dummy comment
27 other_value // other comment
28 };
29
30 void long_function_name(very_long_type x1,
31 very_long_type x2)
32 {
33 const map<string, string> m{
34 { "hostname", "127.0.0.1" },
35 { "port", "6667" }
36 };
37 }
38 };
39 ```
40
41 As a rule of thumb, tabs must always be all length.
42
43 Example of incorrect usage:
44
45 ```cpp
46 { "hostname", "127.0.0.1" },
47 { "port", "6667" }
48 ```
49
50 This example will not align correctly if tabstops are not set to 8.
3 51
4 C++ 52 C++
5 === 53 ===
6 54
7 Style 55 Style
8 ----- 56 -----
9 57
10 - Always use 4 spaces as indentation, 58 - Do not exceed 120 columns for lines of code,
11 - Use UTF-8 charset, 59 - Do not exceed 80 columns for comments,
12 - Use Unix line endings,
13 - Do not exceed 120 characters for lines of code,
14 - Do not exceed 80 characters for comments,
15 - Never write two blank consecutives blank lines,
16 - Do not use bad words.
17 60
18 ### Braces 61 ### Braces
19 62
20 Braces follow the K&R style, they are never placed on their own lines except for 63 Braces follow the K&R style, they are never placed on their own lines except for
21 function definitions. 64 function definitions.
22 65
23 Do not put braces for single line statements except for clarity. 66 Do not put braces for single line statements.
24 67
25 if (condition) { 68 ```cpp
26 apply(); 69 if (condition) {
27 add(); 70 apply();
28 } else 71 add();
29 ok(); 72 } else
30 73 ok();
31 if (condition) 74
32 validate(); 75 if (condition)
33 76 validate();
34 if (foo) { 77
35 state = long + conditional + that + requires + several + lines + 78 if (foo)
36 to + complete; 79 state = long + conditional + that + requires + several + lines +
37 } 80 to + complete;
81 ```
38 82
39 Functions require braces on their own lines. 83 Functions require braces on their own lines.
40 84
41 void function() 85 ```cpp
42 { 86 void function()
43 } 87 {
88 }
89 ```
44 90
45 And a lambda has its braces on the same lines too: 91 And a lambda has its braces on the same lines too:
46 92
47 sort([&] (auto&) { 93 ```cpp
48 return true; 94 sort([&] (auto&) {
49 }); 95 return true;
96 });
97 ```
50 98
51 ### Spaces 99 ### Spaces
52 100
53 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before 101 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before
54 its argument. 102 its argument.
55 103
56 Normal function calls do not require it. 104 Normal function calls do not require it.
57 105
58 if (foo) 106 ```cpp
59 destroy(sizeof (int)); 107 if (foo)
108 destroy(sizeof (int));
109 ```
60 110
61 ### References and pointers 111 ### References and pointers
62 112
63 References and pointers are always next to the type name and not the variable. 113 References and pointers are always next to the type name and not the variable.
64 114
65 T& get(const std::string& name); 115 ```cpp
66 116 auto get(const std::string& name) -> T&;
67 int* p = &x; 117
118 int* p = &x;
119 ```
120
121 ### Trailing return syntax
122
123 We use trailing return syntax everywhere, it has the following benefits:
124
125 - Inner types don't need to be prefixed by class name,
126 - Functions are kept aligned correctly, focusing on the function name.
127
128 ```cpp
129 auto func() -> std::string;
130 ```
68 131
69 ### Naming 132 ### Naming
70 133
71 - English names, 134 - English names,
72 - Member variables have trailing underscore (e.g foo\_bar\_), 135 - Member variables have trailing underscore (e.g foo\_bar\_),
73 - No hungarian notation. 136 - No hungarian notation.
74 137
75 Everything is in `underscore_case` except template parameters and macros. 138 Everything is in `underscore_case` except template parameters and macros.
76 139
77 #if defined(FOO) 140 ```cpp
78 # include <foo.hpp> 141 #if defined(FOO)
79 #endif 142 # include <foo.hpp>
80 143 #endif
81 namespace baz { 144
82 145 namespace baz {
83 class object { 146
84 private: 147 class object {
85 std::string name_; 148 private:
86 149 std::string name_;
87 public: 150
88 inline const std::string& name() const noexcept 151 public:
89 { 152 auto name() const noexcept -> const std::string&;
90 return name_; 153 };
91 } 154
92 }; 155 template <typename Archive>
93 156 void open(const Archive& ar)
94 template <typename Archive> 157 {
95 void open(const Archive& ar) 158 bool is_valid = false;
96 { 159 }
97 bool is_valid = false; 160
98 } 161 } // !baz
99 162 ```
100 } // !baz
101 163
102 ### Header guards 164 ### Header guards
103 165
104 Do not use `#pragma once`. 166 Do not use `#pragma once`.
105 167
106 Header guards are usually named **PROJECT_COMPONENT_FILENAME_HPP**. 168 Header guards are usually named `PROJECT_COMPONENT_FILENAME_HPP`.
107 169
108 #ifndef FOO_COMMON_UTIL_HPP 170 ```cpp
109 #define FOO_COMMON_UTIL_HPP 171 #ifndef FOO_COMMON_UTIL_HPP
110 172 #define FOO_COMMON_UTIL_HPP
111 #endif // !FOO_COMMON_UTIL_HPP 173
174 #endif // !FOO_COMMON_UTIL_HPP
175 ```
112 176
113 ### Enums 177 ### Enums
114 178
115 Enumerations constants are always defined in separate line to allow commenting 179 Enumerations constants are always defined in separate line to allow commenting
116 them as doxygen. 180 them as doxygen.
117 181
118 Enum class are encouraged. 182 Enum class are encouraged.
119 183
120 enum class color { 184 ```cpp
121 blue, 185 enum class color {
122 red, 186 blue,
123 green 187 red,
124 }; 188 green
189 };
190 ```
125 191
126 ### Switch 192 ### Switch
127 193
128 In a switch case statement, you **must** not declare variables and not indent 194 In a switch case statement, you **must** not declare variables and not indent
129 cases. 195 cases.
130 196
131 switch (variable) { 197 ```cpp
132 case foo: 198 switch (variable) {
133 do_some_stuff(); 199 case foo:
134 break; 200 do_some_stuff();
135 default: 201 break;
136 break; 202 default:
137 } 203 break;
204 }
205 ```
138 206
139 ### Files 207 ### Files
140 208
141 - Use `.cpp` and `.hpp` as file extensions, 209 - Use `.cpp` and `.hpp` as file extensions,
142 - Filenames are all lowercase. 210 - Filenames are all lowercase.
143 211
144 ### Comments 212 ### Comments
145 213
146 Avoid useless comments in source files. Comment complex things or why it is done 214 Avoid useless comments in source files. Comment complex things or why it is done
147 like this. However any public function in the .hpp **must** be documented as 215 like this. However any public function in the .hpp **must** be documented as
148 doxygen without exception. 216 doxygen without exception.
149 217
150 /* 218 ```cpp
151 * Multi line comments look like 219 /*
152 * this. 220 * Multi line comments look like
153 */ 221 * this.
154 222 */
155 // Short comment 223
224 // Short comment
225 ```
156 226
157 Use `#if 0` to comment blocks of code. 227 Use `#if 0` to comment blocks of code.
158 228
229 ```cpp
159 #if 0 230 #if 0
160 broken_stuff(); 231 broken_stuff();
161 #endif 232 #endif
233 ```
162 234
163 ### Includes 235 ### Includes
164 236
165 The includes should always come in the following order. 237 The includes should always come in the following order.
166 238
167 1. C++ headers 239 1. C++ headers
168 2. C header 240 2. C header
169 3. Third party libraries 241 3. Third party libraries
170 4. Application headers in "" 242 4. Application headers in ""
171 243
172 #include <cstring> 244 ```cpp
173 #include <cerrno> 245 #include <cstring>
174 246 #include <cerrno>
175 #include <sys/stat.h> 247
176 248 #include <sys/stat.h>
177 #include <libircclient.h> 249
178 250 #include <libircclient.h>
179 #include "foo.h" 251
180 252 #include "foo.h"
181 **Note**: always use C++ headers for C equivalent, stdio.h -> cstdio, etc. 253 ```
182 254
183 ### Commit messages 255 Note: always use C++ headers for C equivalent, stdio.h -> cstdio, etc.
184
185 Commit messages are written using the following syntax:
186
187 Topic: short message less than 80 characters
188
189 Optional additional description if needed.
190
191 Replace `Topic` with one of the following:
192
193 - **CMake**: for the build system,
194 - **Docs**: for the documentation,
195 - **Misc**: for miscellaneous files,
196 - **Tests**: for the unit tests.
197 256
198 Programming 257 Programming
199 ----------- 258 -----------
200 259
201 ### C language 260 ### C language
202 261
203 Do not use old C stuff like `void *`, `srand/rand`, `printf` or anything that 262 Do not use old C stuff like `void*`, `srand/rand`, `printf` or anything that
204 can be rewritten in modern C++. 263 can be rewritten in modern C++.
205 264
206 ### RTTI 265 ### RTTI
207 266
208 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of 267 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of
212 271
213 It is recommended to pass parameters by value or const reference. Usage of 272 It is recommended to pass parameters by value or const reference. Usage of
214 non-const reference as output parameter is **discouraged** and should be avoided 273 non-const reference as output parameter is **discouraged** and should be avoided
215 in many case because it does not allow chaining of expressions like: 274 in many case because it does not allow chaining of expressions like:
216 275
217 std::cout << reverse(upper(clean(" hello world! "))) << std::endl; 276 ```cpp
277 std::cout << reverse(upper(clean(" hello world! "))) << std::endl;
278 ```
218 279
219 If your function is designed to return a modified value passed as argument, it 280 If your function is designed to return a modified value passed as argument, it
220 is better to take it by value and modify it directly. 281 is better to take it by value and modify it directly.
221 282
222 std::string clean(std::string input) 283 ```cpp
223 { 284 auto clean(std::string input) -> std::string
224 if (!input.empty() && input.back() == '\r') 285 {
225 input.pop_back(); 286 if (!input.empty() && input.back() == '\r')
226 287 input.pop_back();
227 return input; 288
228 } 289 return input;
290 }
291 ```
229 292
230 Never pass primitive types as const value. 293 Never pass primitive types as const value.
231 294
232 ### Assertions 295 ### Assertions
233 296
235 errors. 298 errors.
236 299
237 For example, you may use `assert` to verify that the developer access the data 300 For example, you may use `assert` to verify that the developer access the data
238 between the bounds of an array: 301 between the bounds of an array:
239 302
240 T& operator[](unsigned index) 303 ```cpp
241 { 304 auto operator[](unsigned index) -> T&
242 assert(index < length_); 305 {
243 306 assert(index < length_);
244 return data_[index]; 307
245 } 308 return data_[index];
309 }
310 ```
246 311
247 The `assert` macro is not meant to check that a function succeeded, this code 312 The `assert` macro is not meant to check that a function succeeded, this code
248 must not be written that way: 313 must not be written that way:
249 314
250 assert(listen(10)); 315 ```cpp
316 assert(listen(10));
317 ```
251 318
252 ### Exceptions 319 ### Exceptions
253 320
254 You must use exceptions to indicate an error that was unexpected such as: 321 You must use exceptions to indicate an error that was unexpected such as:
255 322
256 - Failing to open a file, 323 - Failing to open a file,
257 - I/O unexpected errors, 324 - I/O unexpected errors,
258 - Parsing errors, 325 - Parsing errors,
259 - User errors. 326 - User errors.
260 327
261 You may use the C++ standard exceptions defined in the stdexcept header but if 328 You may use the C++ standard exceptions defined in the stdexcept header but if
262 you need to carry more data within your exception, you should derive from 329 you need to carry more data within your exception, you should derive from
263 `std::exception`. 330 `std::exception`.
264 331
272 Basic utility functions should be defined in a namespace as a free function not 339 Basic utility functions should be defined in a namespace as a free function not
273 as a static member function, we're doing C++ not Java. 340 as a static member function, we're doing C++ not Java.
274 341
275 Example: 342 Example:
276 343
277 namespace util { 344 ```cpp
278 345 namespace util {
279 std::string clean(std::string input); 346
280 347 auto clean(std::string input) -> std::string;
281 } // !util 348
349 } // !util
350 ```
282 351
283 ### Variables initialization 352 ### Variables initialization
284 353
285 Use parentheses to initialize non primitive types: 354 Use parentheses to initialize non primitive types:
286 355
287 throw std::runtime_error("foo"); 356 ```cpp
288 357 throw std::runtime_error("foo");
289 my_class obj("bar"); 358
359 my_class obj("bar");
360 ```
290 361
291 Use brace initialization when you want to use an initializer list, type 362 Use brace initialization when you want to use an initializer list, type
292 elision: 363 elision:
293 364
294 std::vector<int> v{1, 2, 3}; 365 ```cpp
295 366 std::vector<int> v{1, 2, 3};
296 foo({1, 2}); // type deduced 367
297 368 foo({1, 2}); // type deduced
298 return { "true", false }; // std::pair returned 369
370 return { "true", false }; // std::pair returned
371 ```
299 372
300 Use the assignment for primitive types: 373 Use the assignment for primitive types:
301 374
302 int x = 123; 375 ```cpp
303 bool is_valid = true; 376 int x = 123;
377 bool is_valid = true;
378 ```
304 379
305 ### Classes 380 ### Classes
306 381
307 Classes are usually defined in the following order: 382 Classes are usually defined in the following order:
308 383
309 1. Public inner types (enums, classes), 384 1. Public inner types (enums, classes),
310 2. Protected/private members 385 2. Protected/private members and functions
311 3. Public functions 386 3. Public static functions.
312 387 3. Public member functions
313 class foo { 388 4. Public virtual functions.
314 public: 389
315 enum class type { 390 ```cpp
316 a, 391 class foo {
317 b 392 public:
318 }; 393 enum class type {
319 394 a,
320 private: 395 b
321 int member_{0}; 396 };
322 397
323 public: 398 private:
324 void some_function(); 399 int member_{0};
325 }; 400
401 public:
402 void some_function();
403 };
404 ```
326 405
327 ### Structs 406 ### Structs
328 407
329 Do not use C structs unless you have very good reason to do so. If you want to 408 Use structs for objects that only need to store public data and have no
330 pack some data, just use `class` and make all fields public. 409 invariants. For example PODs and traits match this criteria:
331 410
332 class point { 411 ```cpp
333 public: 412 struct point {
334 int x{0}; 413 int x{0};
335 int y{0}; 414 int y{0};
336 }; 415 };
416
417 template <>
418 struct info_traits<point> {
419 template <typename Archive>
420 static void serialize(Archive& ar, const point& point)
421 {
422 ar.write(point.x);
423 ar.write(point.y);
424 }
425 };
426 ```
337 427
338 ### Return 428 ### Return
339 429
340 The preferred style is to return early in case of errors. That makes the code 430 The preferred style is to return early in case of errors. That makes the code
341 more linear and not highly indented. 431 more linear and not highly indented.
342 432
343 This code is preferred: 433 This code is preferred:
344 434
345 if (a_condition_is_not_valid) 435 ```cpp
346 return nullptr; 436 if (a_condition_is_not_valid)
347 if (an_other_condition) 437 return nullptr;
348 return nullptr; 438 if (an_other_condition)
349 439 return nullptr;
350 auto x = std::make_shared<object>(); 440
351 441 auto x = std::make_shared<object>();
352 x->start(); 442
353 x->save(); 443 x->start();
354 444 x->save();
355 return x; 445
446 return x;
447 ```
356 448
357 Additional rules: 449 Additional rules:
358 450
359 - Do never put parentheses between the returned value, 451 - Do never put parentheses between the returned value,
360 - Do not put a else branch after a return. 452 - Do not put a else branch after a return.
361 453
362 ### Auto 454 ### Auto
363 455
364 We encorage usage of `auto`, it reduces code maintainance as you don't need to 456 We encorage usage of `auto`, it reduces code maintainance as you don't need to
365 change your code when your rename types. 457 change your code when your rename types.
366 458
367 ````cpp 459 ```cpp
368 auto it = std::find_if(v.begin(), v.end(), [&] (const auto& obj) { 460 auto it = std::find_if(v.begin(), v.end(), [&] (const auto& obj) {
369 return obj.key() == "foo"; 461 return obj.key() == "foo";
370 }); 462 });
371 463
372 for (const auto& pair : a_map) 464 for (const auto& pair : a_map)
373 std::cout << pair.first << " = " << pair.second << std::endl; 465 std::cout << pair.first << " = " << pair.second << std::endl;
374 ```` 466 ```
375 467
376 But do not use `auto` to write code like in python, this is not acceptable: 468 But do not use `auto` to write code like in python, this is not acceptable:
377 469
378 ````cpp 470 ```cpp
379 auto o = my_object("foo"); 471 auto o = my_object("foo");
380 ```` 472 ```
473
474 ### String views
475
476 Use `std::string_view` each time you need a string that you will not own, this
477 includes: temporary arguments, return values, compile time constants.
478
479 ```cpp
480 const std::string_view version("1.0");
481
482 void load(std::string_view id, std::string_view path)
483 {
484 std::cout << "loading: " << id << " from path: " << path << std::endl;
485 }
486 ```
487
488 ### Optional values
489
490 Use `std::optional` to indicate a null value considered as valid. For example,
491 searching a value that may not exist.
492
493 ```cpp
494 auto find(std::string_view id) -> std::optional<int>
495 {
496 if (auto it = foo.find(id); it != foo.end())
497 return it->second;
498
499 return std::nullopt;
500 }
501 ```
502
503 ### Avoid definitions in headers
504
505 Try to avoid as much as possible function definition in header file. It slow
506 down compilation because the compiler has to parse the syntax over and over.
507 It's even worse as you may need to recompile a lot of files when you change a
508 header rather than a source file.
509
510 CMake
511 =====
512
513 Style
514 -----
515
516 - Try to keep line shorter than 80 columns
517
518 ### Spaces
519
520 Each programming keyword (e.g. `if`, `foreach`, `while`) requires a single space
521 before its argument, otherwise write opening parenthese directly after.
522
523 ```cmake
524 foreach (c ${COMPONENTS})
525 string(TOUPPER ${c} CMP)
526
527 if (${WITH_${CMP}})
528 add_executable(${c} ${c}.cpp)
529 endif ()
530 endforeach ()
531 ```
532
533 ### Line breaks
534
535 When CMake lines goes too long, you should indent arguments at the same level,
536 it's also common to see named argument values indented even more.
537
538 ```cmake
539 set(
540 FILES
541 ${myapp_SOURCE_DIR}/main.cpp
542 ${myapp_SOURCE_DIR}/foo.cpp
543 ${myapp_SOURCE_DIR}/bar.cpp
544 )
545
546 command_with_lot_of_arguments(
547 TARGET foo
548 INSTALL On
549 SOURCES
550 ${myapp_SOURCE_DIR}/main.cpp
551 ${myapp_SOURCE_DIR}/foo.cpp
552 ${myapp_SOURCE_DIR}/bar.cpp
553 COMMENT "Some comment"
554 ```
555
556 Modern CMake
557 ------------
558
559 CMake evolves over time, if you have read very old articles there is a chance
560 that what you have read is actually deprecated and replaced by other features.
561 The following list is a short summary of modern CMake features that you must
562 use.
563
564 ### Imported targets
565
566 When they are available, use imported targets rather than plain variables. They
567 offer complete dependency tracking with options and include directories as well.
568
569 ```cmake
570 find_package(Boost COMPONENTS system)
571 target_link_libraries(main Boost::system)
572 ```
573
574 ### Generator expressions
575
576 Use generator expressions when it make sense. For example you should use them
577 for variables that are not used at generation time (e.g CMAKE\_BUILD\_TYPE).
578
579 ```cmake
580 target_include_directories(
581 myapp
582 $<BUILD_INTERFACE:${myapp_SOURCE_DIR}>
583 $<INSTALL_INTERFACE:include>
584 )
585 ```
586
587 Warning: do never test against `CMAKE_BUILD_TYPE` in any CMakeLists.txt, IDEs
588 like Visual Studio will mismatch what you'll put in the conditions.
589
590 ### Avoid global scoping
591
592 The following commands must be avoided as much as possible:
593
594 - `link_directories`,
595 - `link_libraries`,
596 - `include_directories`,
597 - `add_definitions`.
598
599 They pollute the global namespace, all targets defined after these commands will
600 be built against those settings. Instead, you should use the per-targets
601 commands.
602
603 ```cmake
604 target_include_directories(
605 mylib
606 PUBLIC
607 $<BUILD_INTERFACE:${mylib_SOURCE_DIR}>
608 $<INSTALL_INTERFACE:include>
609 )
610 target_link_libraries(mylib foo)
611 ```
612
613 ### Defining sources
614
615 You MUST never use any kind of `file(GLOB)` commands to list sources for an
616 executable. CMake is designed to be re-called by itself only when required,
617 having such a construct will not let CMake be able to detect if you have
618 added/removed files in your source directory. Instead, you MUST always specify
619 all source by hands.
620
621 ```cmake
622 set(
623 FILES
624 ${myapp_SOURCE_DIR}/main.cpp
625 ${myapp_SOURCE_DIR}/a.cpp
626 ${myapp_SOURCE_DIR}/b.cpp
627 )
628
629 add_executable(myapp ${FILES})
630 ```
631
632 Markdown
633 ========
634
635 Headers
636 -------
637
638 For 1st and 2nd level headers, use `===` and `---` delimiters and underline the
639 whole title. Otherwise use `###`.
640
641 ```markdown
642 Top level title
643 ===============
644
645 Sub title
646 ---------
647
648 ### Header 3
649
650 #### Header 4
651
652 ##### Header 5
653
654 ###### Header 6
655 ```
656
657 Lists
658 -----
659
660 Use hyphens for unordered lists for consistency, do not indent top level lists,
661 then indent by two spaces each level
662
663 ```markdown
664 - unordered list 1
665 - unordered list 2
666 - sub unordered item
667
668 1. unordered list 1
669 2. unordered list 2
670 2.1. sub unordered item
671 ```
672
673 Code blocks
674 -----------
675
676 You can use three backticks and the language specifier or just indent a block by
677 for leading spaces if you don't need syntax.
678
679 ```cpp
680 std::cout << "hello world" << std::endl;
681 ```
682
683 And without syntax:
684
685 ```markdown
686 This is simple code block.
687 ```
688
689 Tables
690 ------
691
692 Tables are supported and formatted as following:
693
694 ```markdown
695 | header 1 | header 2 |
696 |----------|----------|
697 | item 1 | item 2 |
698 ```
699
700 Alerts
701 ------
702
703 It's possible to prefix a paragraph by one of the following topic, it renders a
704 different block depending on the output format:
705
706 - Note:
707 - Warning:
708 - Danger:
709
710 Then, if the paragraph is too long, indent the text correctly.
711
712 ```markdown
713 Note: this is an information block that is too long to fit between the limits so
714 it is split and indented.
715 ```