summary refs log tree commit diff
path: root/C-STYLE.md
blob: cde86cc2c663642c6d738bbc36a53557f056740a (plain) (blame)
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
# Leah Neukirchen's C Style Guide

You may not like all rules presented here, but they work very well for
me and have helped producing high quality code.  Everyone is free to
code however they want, write and follow their own style guides, but
when you contribute to my code, please follow these rules:

This guide does not explain how to write good C code,
but merely how to format it.

## Formatting:

* Use ASCII (UTF-8 is ok in comments, if you have to).

* Use Unix-style line endings.  On the last line of the file, too.

* Use lowercase file names, use `.c` and `.h` extensions.

* Write valid C99.  Target POSIX.1-2008 as a base line.

* Use 1 tab for each level of indentation, 4 spaces for half-indentation.

* Keep lines fewer than 80 characters, with 8 space tabs.

* Do not use tabs for aligning, only for indentation.
  Do not use tabs in the middle of the line.
  Do not align variable names in declarations,
  use one space between type and name.
  Do not align wrapped function calls, half-indent instead.

* Use K&R indentation:
  * `{ }` of the function are in column 1.
  * `{ }` of control structures start in the same line.
    Closing and opening braces go on the same line as the else.
  * Indent case deep as switch.

* Use ANSI function declarations only.

* Function names start in column 1, types go in the line before.

* Avoid `{ }` around single statements.

* Use `{ }` consistently in if/else-if/else when one branch uses it.

* For dangling else, use `{ }` around the outer if:

		if (bar) {
			if (foo)
				foo();
			else
				notfoo();
		}

* Use spaces around assignments and comparisons,
  after keywords, commas, colons and semicolons,
  around `{` and before `}`, and around `? :`.

* No space between function name and arguments.

* No spaces after `(`, `[` and before `]`, `)`.

* No spaces after unary operators.

* Use semantic spaces around operators, e.g. write `x * y`, `8*x + 6*y`.

* Indent labels in column 1.  (Exception: labels belonging to a
  switch-case are indented like the case.)

* Use an empty line after local variable declarations.

* Use an empty line before the return statement of a function (unless it
  only has one line), and an empty line between functions.

* Don't use `( )` around the argument of return.

* Use empty lines to break up a long functions into logical paragraphs.

* Break lines after `&&` and `||`, not before.

* Avoid trailing whitespace.

* The pointer star belongs to the variable, not to the type.
  Write `char * strdup(char *str)`.

* Write casts like `(char *)foo`.  Do not use a space after a cast.

* Don't use parentheses after sizeof, unless its a type, then use a
  space between: `sizeof buf` and `sizeof (struct foo)`.
  Prefer sizeof with variable names.

* Do not cast `(void *)`.

* Use `<stdint.h>` and its types freely.

* Use `size_t` for array indices and string lengths.

* Order `#include` alphabetically in three blocks:
  * `<sys/...>`
  * `<...>`
  * `"..."`.

* Put each statement on its own line.
  Exception: short guards ala `if (...) break;` or `if (...) goto fail;` are ok.

* Declare functions `static` when they are only used in this translation unit.

* Use lowercase hexadecimal digits.

## Idioms:

* Using the return value of `=` is ok.

* Use `while (1) ...` for infinite loops.

* Initialize zeroed structs using `= { 0 }`.

* Prefer `i++` over `++i`.

* Prefer `*x` over `x[0]`
  (unless the same code also accesses `x[1]`, `x[2]` etc.)

* Prefer `x+i` over `&x[i]`.

* Do not use `NULL`.  Use `0` for null pointers.
  Remember to use `(char *)0` as a sentinel for execl(3).

* Avoid superfluous comparison to 0.
  * Exception:  Use `== 0` when 0 is the successful result, e.g.
    `strcmp(a, b) == 0`, `access(file, F_OK) == 0`, `regexec(...) == 0`.
  * Do not use `!strcmp(a, b)`.
  * Use `if (!p) ...` to check whether `p` is a null pointer.

* Don't use Yoda conditions (`0 == x`).

* Use a plain `;` on a line of itself for the empty instruction.

* Avoid `typedef` to name structs.

* Use `typedef` to name function pointers.

* Only initialize variables when it is sensible.

* Use `int` variables to store boolean values in general.

* Avoid bit fields unless you absolutely need to save space.

* Avoid forward declarations unless indispensable.
  Let `main` be the last function in code.

## Naming:

* The length of an identifier determines its scope.

* Respect POSIX namespaces: http://port70.net/~nsz/c/posix/reserved.txt
  Do not use `_t` suffix for types.

* Use `snake_case` for functions, variables, and types.

* Use `SCREAMING_SNAKE_CASE` for macros.

* Use `Xflag` for the value of the command line flag `-X`.

* Use a suffix `o` to mark output parameters.

* Use a consistent prefix for all global names in a library.

## Comments:

* Comments longer than a word are capitalized and use punctuation.
  Use two spaces after periods.

* Write single line comments like this:

		/* foo */
		// C++ style is also ok.

* Use at least two spaces before end-of-line comments in a code line.

* Write multi-line comments like this:

		/*
		 * Important comments
		 * at the beginning of the file.
		 */

		/* Inline comments
		   that can span
		   multiple lines. */

* Avoid superfluous comments.

## The rest:

* Avoid long functions.

* Avoid long parameter lists.

## General:

* Do not mutate arguments unless that is the purpose of the function.

* Keep the code simple.

* Don't overdesign.

* Don't underdesign.

* Avoid bugs.

* Read other style guides and apply the parts that don't dissent with
  this list.

* Be consistent.

* Use common sense.