-
Notifications
You must be signed in to change notification settings - Fork 59
/
CODING_STYLE
287 lines (208 loc) · 7.03 KB
/
CODING_STYLE
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
trace-cmd coding-style
======================
The coding style of trace-cmd and the tracing libraries (libtracefs and
libtraceevent) are very similar to the Linux kernel coding style:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/coding-style.rst
Indentation
===========
Tabs are used for the start of indentation (the '\t' character), and should be
set to 8 characters. Spaces may be used at the end for continued lines where
having the start of text line up to braces in the previous line is not
divisible by 8.
Max line width
==============
All lines should not be more than 100 characters in length.
This is a guide, as readability is more important than breaking lines up into a
hard limit. Ideally, strings should never be broken up except for where a new
line is added.
printf("This is a line that may continue for a very long string.\n"
"This is another line, but after a new line\n");
But line breaks should not be:
printf("This is a line that may continue for a very"
"long string.\n This is another line,"
"but after a new line\n");
Not only is the above not as readable as the first version, it is not
even equivalent, because it is missing spaces between the line breaks.
For this reason, finish the string on the same line, even if that string
breaks the 100 character limit.
Brackets and braces
===================
For all conditionals, the braces start on the same line:
if (cond) {
}
And the ending brace is at the same indentation as the conditional.
while (cond) {
}
do {
} while (cond);
for (i = 0; i < 10; i++) {
}
The same is true for structures:
struct my_struct {
int field;
};
But for functions, the braces should start on the following line:
void my_function(void)
{
}
It is also fine to not use braces for simple conditionals and loops.
if (!x)
y = x;
else
y = 1;
for (i = 0; i < 10; i++)
foo(i);
while (getline(&line, &size, fp) > 0)
printf("%s", line);
But any complex or multiline conditional or loop should have braces even if it
is allowed not to by the C language.
if (x) {
for (i = 0; i < 10; i++)
foo(i);
} else {
foo(1);
}
Notice above that even though the else portion is simple, it too has braces as
the else and if blocks should match. If one is required to have braces, they
both should have braces.
Spaces
======
A single space should be used between C commands and their starting
parenthesis.
if (x)
for (i = 0; i < 10; i++)
while (getline(&line, &size, fp) > 0)
There should be no space between function or macros and the starting
parenthesis.
foo(x)
IS_VALID(y)
This includes prototypes and declarations.
void foo(int x)
A space should be before and after assignment, comparison and algorithmic
signs.
i = 0;
if (i < 10)
if (i == 5)
y = i + 10;
i += 5;
For structures, use tabs to make all the fields line up nicely.
struct {
int foo;
int bar;
unsigned long long time;
};
Variable declarations
=====================
The order of variables that are declared, should first keep the same types
together, but also should be ordered by their length such that the variables
are ordered in an "upside-down Christmas tree" fashion where the length gets
smaller.
int tracecmd_count_cpus(void)
{
static int once;
char buf[1024];
int cpus = 0;
char *pbuf;
size_t *pn;
FILE *fp;
size_t n;
int r;
The above shows that the order is done by length, and in the above example it
also shows that "int cpu = 0;" is not grouped next to "int r;". As this is more
of a guideline and made to be more aesthetic to the eye of the reader, both the
above and is acceptable as below.
int tracecmd_count_cpus(void)
{
static int once;
char buf[1024];
char *pbuf;
size_t *pn;
FILE *fp;
size_t n;
int cpus = 0;
int r;
Unless variables are tightly related, it is expected that each variable be on
its own line and not grouped by type. That is,
int r, cpus = 0;
is to be discouraged, as the two variables are not related to each other.
But if you had a bunch of counters:
int i, j, k;
That would be fine, as the variables are all related as they are all for the
same purpose (arbitrary counters). The same may go with pointers;
char *begin, *end;
Comments
========
Comments will use the "/* */" format and the C++ "//" style is discouraged.
If a comment is on one line, keep the "/*" and "*/" on the same line:
/* This is a single line comment. */
If a comment spans more than one line, then have the "/*" on a separate line
before the comment and the "*/" on a separate line at the end of the comment,
and each line starts with a "*" where all the "*" line up with each other.
/*
* This is a multi line comment, where all the '*'
* will line up, and the text is on a separate line
* as the start and end markers.
*/
Function documentation
======================
All global functions (and especially any APIs) should have a function
description in the form of "kernel doc":
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html
The form is:
/**
* function_name() - Brief description of function.
* @arg1: Describe the first argument.
* @arg2: Describe the second argument.
* One can provide multiple line descriptions
* for arguments.
*
* A longer description, with more discussion of the function function_name()
* that might be useful to those using or modifying it. Begins with an
* empty comment line, and may include additional embedded empty
* comment lines.
*
* The longer description may have multiple paragraphs.
*
* Context: Describes whether the function can sleep, what locks it takes,
* releases, or expects to be held. It can extend over multiple
* lines.
* Return: Describe the return value of function_name.
*
* The return value description can also have multiple paragraphs, and should
* be placed at the end of the comment block.
*/
Structure layout
================
This is more about compaction than coding style. When creating structures, be
aware that if the fields are placed together without being sized by alignment,
that the compiler will create "holes" in them.
struct {
int x;
char y;
unsigned long long f;
};
As int is 4 bytes in length, char is one byte, and unsigned long long is 8
bytes. The compiler will try to naturally align them by their size, and will
include padding (holes) inside the structure to do so. The above is equivalent
to:
struct {
int x;
char y;
char padding[3];
unsigned long long f;
};
It is best to try to organize the structure where there are no holes within
them.
struct {
unsigned long long f;
int x;
char y;
};
The above is better formatting, even if there may be padding outside the
structure, but the compiler will still have more flexibility to utilize the
space outside the structure than what it can do within it.
General
=======
As stated, this is a guide and may not be strictly enforced. The goal is to
have consistent and readable code. In general, try to have the coding style
match the surrounding code.