Chi-Tech
devman_01_03_codingconv.h
Go to the documentation of this file.
1/**\page DevManCodeConventions Coding conventions
2
3 \section sec0 Coding conventions
4
5 In general we follow the
6 <a href="https://google.github.io/styleguide/cppguide.html">Google C++ style guide</a>.
7 We now will dictate a few specific items. Refer to the image below for different
8 text case-namings:
9 \image html "Cases.png" "Different case names and how they look" width=220px
10 \n\n
11 Let us say it here explicitly, <B>all variable-, function-, method- names should be descriptive</B>,
12 avoid abbreviation, rather sacrifice horizontal space for readability.
13
14 \subsection devman1_sec0_1 File names
15
16 - <B>Filenames</B> should be all lower case and may include "_" underscores. i.e.
17 chi_tech_main.cc. snake_case is preferred.
18 - Do not uses dashes `-` in file names
19 - Do not uses dashes spaces in file names (Them Windows users!)
20 - Do not use filenames that already exist in `/usr/include`
21 - In general, make your filenames very specific. For example, use
22 `http_server_logs.h` rather than `logs.h`. A very common case is to have a pair
23 of files called, e.g., `foo_bar.h` and `foo_bar.cc`, defining a
24 class called `FooBar`
25 - Header files have a `.h` extension, c/c++ code files have a `.cc` extension.
26 - Classes and Categorical functions should be contained in their own folder
27 unless they are simple.
28 - Folder depth shall be kept to a minimum and not exceed a depth of 3
29 sub-levels unless very well justified, i.e. `math/Discretization/PWL`
30 - Within a class folder the class declaration must be contained in its own
31 header file. Exceptions to this are allowed for templates and in-line
32 functions
33 - When the member methods/functions become very large, consider functionally
34 splitting them. I.e. use:
35 - classname_00_constrdestr.cc for the constructor and destructor
36 - classname_01_init.cc for an initialize call
37 - classname_02_ops.cc for numerous small operations.
38
39\image html "DevMan_Filenames.png" "Example 1" width=300px
40
41 - If the class is really small then it should have a header file and an
42 associated .cc file
43
44 \image html "DevMan_Filenames1.png" "Example 2" width=350px
45
46\subsection devman1_sec0_2 General code
47
48 - <B>Variables</B> use snake_case, must use lower case and include "_" between words. i.e.
49 num_faces. Variable must not start or end with an underscore.
50 - <B>class Members</B> same as variables but with a trailing "_". `struct`
51 members do not need trailing underscores. See more about this below.
52 - <B>Namespaces</B> use snake_case, should be lower case and may include underscores
53 - <B>FunctionNames</B> use PascalCase, have no underscores and each word starts with a capital
54 letter. Underscores can be allowed in some circumstances.
55 - <B>Classes, structures, and types</B> use PascalCase, have each
56 word start with a capital letter. For example chi_mesh::Vector is a structure
57 called Vector and is defined in the namespace chi_mesh.
58 - <B>enums and constants</B> use SCREAMING_SNAKE_CASE.
59
60\code
61int good_variable_name; // Good variable name
62int bvm; // Bad variable name
63int DontUseThisName; // Do not name variables with capital
64
65void ThisIsAFunctionName(int parameter1)
66{
67 return;
68}
69
70class CoolDataStructure // Standalone class declaration
71{
72public:
73 int data;
74};
75
76namespace my_space // Namespace definition
77{
78 class CoolerDataStructure;
79};
80
81
82class my_space::CoolerDataStructure
83{
84public:
85 int data;
86};
87
88class my_space::CoolerDataStructure {
89public:
90 int data;
91};
92\endcode
93
94## More on Class member conventions
95- All class members should be named the same as regular variables, but with
96 a trailing underscore ('_'), e.g., `cell.centroid_`.
97- `struct` members should NOT be followed by an underscore.
98- Strongly consider making all class members `private/protected` unless
99 - They are `const`.
100 - They cause a sensitivity to speed, e.g., `chi_mesh::cell` does not have
101 accessor functions because `cell.vertex_ids_` is faster than
102 `cell.GetVertexIDs()`
103- References to `private/protected` members should be obtained with a method
104 call. A recommended convention is starting the method call with `Get`, e.g.,
105 `object.member` should be referenced with
106 `object.GetMember()`. This is only guidance. It is perfectly fine to have
107 `object.Member()` or anything that makes sense for the given use case.
108- Use `const` and non-`const` getters judicially. Favor using setters over
109 non-const reference if possible, e.g., setting a single value can be done
110 with `GetSingleValue`/`SetSingleValue`, however, vector manipulation might
111 be better done with `GetVector` followed by manipulations.
112
113\subsection devman1_sec0_3 Tabs, spaces and braces
114
115In order to save horizontal space standard indents are to be 2 spaces instead
116of 4 space equivalent tabs. Other than this the convention is flexible.\n\n
117
118Curly braces, parentheses and block braces does not have a specific requirement
119other than being used in a sense that is optimal with respect to readibility.\n\n
120
121Generally we require that code span a maximum of 80 characters. This is not
122a hard rule but will greatly enhance code reliability. Especially in
123split-screen configurations.
124
125\subsection devman1_sec0_4 Constants and Enumerators
126
127Constants should look like macros. Constants can be defined in macros, enumerations or within
128code segments.
129
130\code
131#define PI 3.1415926535898
132
133int DEFAULT_SETTING1 = 1;
134
135enum AlternateUrlTableErrors {
136 OK = 0,
137 OUT_OF_MEMORY = 1,
138 MALFORMED_INPUT = 2,
139};
140\endcode
141
142\subsection devman1_sec0_5 Comments
143
144 Be consistent in using comments. Comments should be clear and concise and
145 convey the algorithm. Every class, structure or function should be
146 supplied with doxygen comment styles at the top of the item.
147
148\include "../../Modules/DiffusionSolver/lua/diffusion_execute.cc"
149
150## Annotating Class-declerations:
151<B>MAXIMIZE SCOPE MINIMIZE SPACE</B>.
152Class declerations must always happen within header files and should aim to
153provide the maximum amount of scope <B>within the minimum amount of vertical
154space.</B> Member variables/structures should be on the top portion of the
155class decleration and methods should be on the bottom.
156
157 \section devman1_sec1 Header files
158
159 - Avoid using header files for code definition. Use only for
160 struct/class/function declaration
161 - Use <B>#ifdef</B> guards on all header files
162 - Avoid using forward declarations. Use header files instead.
163 - Maintain a consistent order of include files.
164
165 \subsection devman1_sec1_1 General rules
166 Header files are primarily used to make function/class/struct declarations
167 available to other compile units without the need to compile the associated
168 definitions. Unless you have a good reason to do so, do not define code within
169 header files. It results in extra compile times and is considered not good
170 practice. Of course there are exceptions like templating but in general code
171 definitions should be contained in .cc files, <B>header files are for code
172 declaration only</B>.
173
174 \subsection devman1_sec1_2 The #ifndef guard
175 All header files should have #define guards to prevent multiple inclusion.
176 The format of the symbol name should be _<CATEGORY>_<FILE>_H_.
177 To guarantee uniqueness, they should be based on the full path in a project's
178 source tree. For example, the file foo/src/bar/baz.h in project foo should
179 have the following guard:
180
181 \code
182#ifndef FOO_BAR_BAZ_H_
183#define FOO_BAR_BAZ_H_
184
185...
186
187#endif // FOO_BAR_BAZ_H_
188 \endcode
189
190 \subsection devman1_sec1_3 Forward declarations
191 Avoid using forward declarations where possible.
192 Just #include the headers you need.
193
194
195\section devman1_sec2 Namespace hell and typedefinitions
196
197<B>Don't use the "using namespace" directive</B>. Rather rename
198groups of namespaces. Use "typedef" where appropriate.
199
200
201\code
202// Forbidden -- This pollutes the namespace.
203using namespace foo;
204
205// Shorten access to some commonly used names in .cc files.
206namespace baz = ::foo::bar::baz;
207
208// Type definition for each cell there is a pair, number of faces and
209// face areas for each face
210typedef std::vector<std::pair<int, std::vector<double>>> CellFaceAreas;
211
212CellFaceAreas cell_face_areas;
213\endcode
214
215
216\section devman1_sec3 Other general items
217
218\subsection devman1_sec3_0 Line length
219
220Each line of text in your code should be at most 80 characters long.
221A line may exceed 80 characters if it is
222
223- a comment line which is not feasible to split without harming
224 readability, ease of cut and paste or auto-linking -- e.g.
225 if a line contains an example command or a literal URL longer
226 than 80 characters.
227- a raw-string literal with content that exceeds 80 characters.
228 Except for test code, such literals should appear near
229 the top of a file.
230- an include statement.
231- a header guard
232
233
234\subsection devman1_sec3_1 Boolean expressions
235
236When you have a boolean expression that is longer than the
237 standard line length, be consistent in how you break up the lines.
238
239In this example, the logical AND operator is always at the end
240 of the lines:
241
242\code
243if (this_one_thing > this_other_thing &&
244 a_third_thing == a_fourth_thing &&
245 yet_another && last_one) {
246 ...
247}
248\endcode
249
250\subsection devman1_sec3_2 Constructor Initializer lists
251
252Constructor initializer lists can be all on one line or with
253 subsequent lines indented four spaces.
254
255The acceptable formats for initializer lists are:
256
257\code
258// When everything fits on one line:
259MyClass::MyClass(int var) : some_var_(var) {
260 DoSomething();
261}
262
263// If the signature and initializer list are not all on one line,
264// you must wrap before the colon and indent 4 spaces:
265MyClass::MyClass(int var)
266 : some_var_(var), some_other_var_(var + 1) {
267 DoSomething();
268}
269
270// When the list spans multiple lines, put each member on its own line
271// and align them:
272MyClass::MyClass(int var)
273 : some_var_(var), // 4 space indent
274 some_other_var_(var + 1) { // lined up
275 DoSomething();
276}
277
278// As with any other code block, the close curly can be on the same
279// line as the open curly, if it fits.
280MyClass::MyClass(int var)
281 : some_var_(var) {}
282\endcode
283
284\subsection devman1_sec3_3 Operators
285
286Spacing between operators is flexible.
287
288\code
289// Assignment operators always have spaces around them.
290x = 0;
291
292// Other binary operators usually have spaces around them, but it's
293// OK to remove spaces around factors. Parentheses should have no
294// internal padding.
295v = w * x + y / z;
296v = w*x + y/z;
297v = w * (x + z);
298
299// No spaces separating unary operators and their arguments.
300x = -5;
301++x;
302if (x && !y)
303 ...
304\endcode
305
306\subsection devman1_sec3_4 Templates
307
308\code
309// No spaces inside the angle brackets (< and >), before
310// <, or between >( in a cast
311std::vector<string> x;
312y = static_cast<char*>(x);
313
314// Spaces between type and pointer are OK, but be consistent.
315std::vector<char *> x;
316\endcode
317
318\subsection devman1_sec3_5 Casting
319
320In general there are three variants of casting; C-style casting, `static_cast`
321and `dynamic_cast`.
322
323\code
324double aa = 10.5;
325
326float a = (float)aa; // C-style (Use only for numerics)
327float b = static_cast<float>(aa); // static_cast
328float c = dynamic_cast<float>(aa); // dynamic_cast
329\endcode
330
331The difference between the 3 are as follows: C-style casting is a brute-force
332way of casting one type into another. In most, if not all cases, the compiler
333will not provide any protection against casts that will be illegal. The better
334alternative is to use `static_cast` which will allow the compiler to determine
335whether the cast would be legal in a broad scope sense (i.e. casting parent
336pointer to child pointer). If the user needs to check for a valid cast, it is
337often better to use `dynamic_cast` which will return null if the cast is
338illegal, however, be aware that this uses RTTI and therefore has some cost.
339The following conventions therefore apply:
340
341- Use C-style casting only for numerical values
342- Objects and structures should use either `static_cast` or `dynamic_cast`
343
344 */