-
Notifications
You must be signed in to change notification settings - Fork 53
/
coding_style.txt
227 lines (196 loc) · 6.89 KB
/
coding_style.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// CODING STYLE
// following rules should be obeyed when writing new SSR code and overhauling
// old code.
// there are always exceptional cases where these rules don't apply, but they
// should always be taken into consideration.
// maximum line length 80 characters (using 2 spaces for each indentation).
// no TAB characters are used!
// typenames get a '_t' postfixed if appropriate
typedef int my_counter_t;
// variable names in lowercase letters, words separated by underscore (_)
my_counter_t my_counter = 3;
// in the most cases, full words should be used. no abbreviations.
sr_it = fr_it + bl_sz; // bad.
second_read_iterator = first_read_iterator + block_size; // better.
// opening brace on new line. Always on same indentation level as closing brace.
// exception: empty braces: {}
if (something)
{
a = c;
do_something();
}
else // comment for the "else" part
{
a = b;
do_something_else();
// no empty line before closing brace
}
// if (and only if) it can be written in one line, braces can be omitted:
if (something) a = c;
// PARENTHESES, SPACES
//
// no space between function name and opening parenthesis,
// nor after ( and [
// nor before , ) ] and ;
// in most cases, no space before [
// no space before comma but 1 space afterwards.
my_function ( arg1, arg2 ) ; // bad
my_function(arg1, arg2); // better
// but: spaces after if, for, while, switch, ...
// spaces around operators are generally recommended, but sometimes it looks
// nicer without ...
result = (a + b) * factor;
// never use more than one empty line.
// * and & are next to the types, not next to the variables
float *data; // bad, old-school C-style
float* data; // better
// CLASSES
//
// traditional class names start with a capital letter per word (CamelCase),
// no underscores (_), no hideous prefix like in 'CMyClass'.
// "special" classes (traits, iterators, policies, ...) can be in lowercase and
// may use underscores.
class MyClass : public MyBaseClass
{
public:
// no empty line between public/protected/private and following line
// but empty line before it, except if there is an opening brace ({)
MyClass();
// similar functions grouped together without newlines
void my_function1(int my_argument);
bool my_function2(const std::string my_string);
// also add "virtual" in inherited functions (once virtual - always virtual)
virtual my_base_function(int base_argument);
int public_val1;
private:
// private (and protected) member variables and member functions are
// "uglified" with '_'
int _priv_val1;
int _priv_val2;
}
// constructor initiator lists
//
// first line starts with : all others with ,
// each member variable gets its own line.
MyClass::MyClass()
: public_val1(99)
, _priv_val1(129)
, _priv_val2(0)
{}
// within the class implementation, non-uglified functions/variables are used
// with a prefixed "this->".
// This is redundant, but it helps to show where a function/variable belongs to.
my_function1(2); // unclear where this function comes from (is it global?)
this->my_function1(3); // better.
_priv_val1 = 42;
// clear: it has to be a class member (because uglified = private/protected)
// NAMESPACES
//
// namespaces follow the same naming conventions as classes, but names can be in
// lowercase letters.
// there is no extra indentation level for a namespace!
namespace mynamespace
{
int my_namespace_member(int arg);
}
// if a namespace member is implemented in a .cpp file, the namespace is
// prepended to the function name
mynamespace::my_namespace_member(int arg) { return 42; }
// TYPE CASTING
//
// use C++ casting instead of C-style casting
float value;
int step;
step = (int)value; // not good, this should only be used in C
step = static_cast<int>(value); // better
// LINE BREAKS
//
// as mentioned before, maximum line length should be 80 characters.
// if a function definition doesn't fit on a line, consider breaking after the
// return type.
// if lines are broken at operators or punctuation marks, those should end up at
// the beginning of the second line.
int my_very_special_and_long_function(my_rather_special_data_t input1
, my_rather_special_data_t input2)
{
my_very_long_result = 27 * my_other_very_special_and_long_function(input1)
+ my_other_very_special_and_long_function(input2);
return my_very_long_result * my_very_long_result;
}
// if the declaration of a for-loop doesn't fit on one line, put each semicolon
// on a new line
for (MyContainerClass::iterator i = my_container.begin()
; i != my_container.end()
; ++i)
{
do_something(*i);
}
// template definitions always go on their own line, return types, especially if
// they are nested types, may also use their own line
template<typename T>
T::my_inner_type
some_function(const T& input)
{
// ...
return something;
}
// COMPILER WARNINGS
//
// compiler warnings should be taken seriously.
//
// if a function has to be defined but is not implemented, one can use following
// workaround to avoid the warning about an unused variable:
void my_function(int unused_arg)
{
(void)unused_arg; // no "unused variable" warning is shown.
}
// this is another possibility:
void my_function(int /* unused_arg */) {}
// at least following warnings should be used:
// -W -Wall -pedantic -Wpointer-arith -Wcast-align -Wwrite-strings
// -Wredundant-decls -Wno-long-long -Wconversion
//
// shadowing should be avoided and can be checked by -Wshadow
//
// suggestions from Meyers' "Effective C++" can be activated by -Weffc++
// COMMENTS
//
// one-line comments should always use "//".
// if a comment is on the same line as actual source code, it's separated by two
// spaces.
// multi-line comments should always have an empty line before them.
//
// C-style comments (/* ... */) should only be used for
// function/class/file/...-headers (mainly with Doxygen) and not within
// functions.
// Remember: C-style comments cannot be nested!
#if 0
Code can also be deactivated by surrounding it with #if 0 ... #endif
#endif
// DOXYGEN COMMENTS
//
// everything should be documented, doxygen should run without warnings.
//
// the abovementioned rules for C and C++-style comments apply.
// especially, there should be an empty line before multi-line comments.
// C-style comments should only be used for class and function documentation and
// should have more or less this form:
/** Brief description (ending with a dot!).
* Afterwards, there can be a longer description.
* This kind of comments should only be used if there are at least three lines
* of text.
* @tparam T Template parameter
* @param x Input parameter
* @param[out] y Parameter used as output
* @param[in,out] z Parameter used as input and output
* @return Documentation of the return value
* @throw std::runtime_error Documentation of the exception
**/
template<typename T>
T example_function(const T& x, T& y, T& z)
{
y = x + z++;
if (y == z) throw std::runtime_error("y and z are equal!");
return x * y;
}
// vim:filetype=cpp