Reactos
1# Coding Style
2
3This article describes general coding style guidelines, which should be used for new ReactOS code. These guidelines apply exclusively to C and C++ source files. The Members of ReactOS agreed on this document in the October 2013 meeting.
4
5As much existing ReactOS code as possible should be converted to this style unless there are reasons against doing this (like if the code is going to be rewritten from scratch in the near future). See [Notes on reformatting existing code](#notes-on-reformatting-existing-code) for more details.
6
7Code synchronized with other sources (like Wine) must not be rewritten. [3rd Party Files.txt](https://github.com/reactos/reactos/blob/master/media/doc/3rd%20Party%20Files.txt) and [WINESYNC.txt](https://github.com/reactos/reactos/blob/master/media/doc/WINESYNC.txt) files can be used for tracking synchronized files.
8
9## File Structure
10
111. Every ReactOS source code file should include a file header like this:
12
13```
14/*
15 * PROJECT: ReactOS Kernel
16 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
17 * PURPOSE: Does cool things like Memory Management
18 * COPYRIGHT: Copyright 2017 Arno Nymous <abc@mailaddress.com>
19 * Copyright 2017 Mike Blablabla <mike@blabla.com>
20 */
21```
22
23Please use SPDX license identifiers available at https://spdx.org/licenses.
24This makes our source file parseable by licensing tools!
25
26You should add yourself to the `COPYRIGHT` section of a file if you did a major contribution to it and could take responsibility for the whole file or a part of it. Not more than 3 people shall be in that list for each file.
27
28`FILE` line of the old header should be removed.
29
302. [Doxygen](https://doxygen.reactos.org/) documentation generator is used for ReactOS codebase, so use a proper header for functions, see [API Documentation](https://reactos.org/wiki/Documentation_Guidelines#API_Documentation) for details.
31
32## Indentation and line width
33
341. Line width must be at most **100 characters**.
352. Do not add a space or tab at the end of any line.
363. Indent with **4 spaces**, don't use tabs!
374. Indent both a case label and the case statement of a switch statement.
38
39**Right:**
40```c
41switch (Condition)
42{
43 case 1:
44 DoSomething();
45 break;
46
47 case 2:
48 {
49 DoMany();
50 ManyMore();
51 OtherThings();
52 break;
53 }
54}
55```
56
57**Wrong:**
58```c
59switch(Condition)
60{
61case 1:
62 DoSomething();
63 break;
64case 2:
65 DoMany();
66 ManyMore();
67 OtherThings();
68 break;
69}
70```
71
725. When a function call does not fit onto a line, align arguments like this:
73```c
74FunctionCall(arg1,
75 arg2,
76 arg3);
77```
78
796. Function headers should have this format (preserving the order as in the example):
80```c
81static // scope identifier
82CODE_SEG("PAGE") // section placement
83// other attributes
84BOOLEAN // return type
85FASTCALL // calling convention
86IsOdd(
87 _In_ UINT32 Number);
88```
89
90## Spacing
91
921. Do not use spaces around unary operators.
93**Right:** `i++;`
94**Wrong:** `i ++;`
95
962. Place spaces around binary and ternary operators.
97**Right:** `a = b + c;`
98**Wrong:** `a=b+c;`
99
1003. Do not place spaces before comma and semicolon.
101
102**Right:**
103```c
104for (int i = 0; i < 5; i++)
105 DoSomething();
106
107func1(a, b);
108```
109
110**Wrong:**
111```c
112for (int i = 0; i < 5 ; i++)
113 DoSomething();
114
115func1(a , b) ;
116```
117
1184. Place spaces between control statements and their parentheses.
119
120**Right:**
121```c
122if (Condition)
123 DoSomething();
124```
125
126**Wrong:**
127```c
128if(Condition)
129 DoSomething();
130```
131
1325. Do not place spaces between a function and its parentheses, or between a parenthesis and its content.
133
134**Right:**
135```c
136func(a, b);
137```
138
139**Wrong:**
140```c
141func (a, b);
142func( a, b );
143```
144
145## Line breaking
146
1471. Each statement should get its own line.
148
149**Right:**
150```c
151x++;
152y++;
153
154if (Condition)
155 DoSomething();
156```
157
158**Wrong:**
159```c
160x++; y++;
161
162if (Condition) DoSomething();
163```
164
165## Braces
166
1671. Always put braces (`{` and `}`) on their own lines.
1682. One-line control clauses may use braces, but this is not a requirement. An exception are one-line control clauses including additional comments.
169
170**Right:**
171```c
172if (Condition)
173 DoSomething();
174
175if (Condition)
176{
177 DoSomething();
178}
179
180if (Condition)
181{
182 // This is a comment
183 DoSomething();
184}
185
186if (A_Very || (Very && Long || Condition) &&
187 On_Many && Lines)
188{
189 DoSomething();
190}
191
192if (Condition)
193 DoSomething();
194else
195 DoSomethingElse();
196
197if (Condition)
198{
199 DoSomething();
200}
201else
202{
203 DoSomethingElse();
204 YetAnother();
205}
206```
207
208**Wrong:**
209```c
210if (Condition) {
211 DoSomething();
212}
213
214if (Condition)
215 // This is a comment
216 DoSomething();
217
218if (A_Very || (Very && Long || Condition) &&
219 On_Many && Lines)
220 DoSomething();
221
222if (Condition)
223 DoSomething();
224else {
225 DoSomethingElse();
226 YetAnother();
227}
228```
229
230## Control structures
231
2321. Don't use inverse logic in control clauses.
233**Right:** `if (i == 1)`
234**Wrong:** `if (1 == i)`
235
2362. Avoid too many levels of cascaded control structures. Prefer a "linear style" over a "tree style". Use `goto` when it helps to make the code cleaner (e.g. for cleanup paths).
237
238**Right:**
239```c
240if (!func1())
241 return;
242
243i = func2();
244if (i == 0)
245 return;
246
247j = func3();
248if (j == 1)
249 return;
250...
251```
252
253**Wrong:**
254```c
255if (func1())
256{
257 i = func2();
258 if (func2())
259 {
260 j = func3();
261 if (func3())
262 {
263 ...
264 }
265 }
266}
267```
268
269## Naming
270
2711. Capitalize names of variables and functions. Hungarian Notation may be used when developing for Win32, but it is not required. If you don't use it, the first letter of a name must be a capital too (no lowerCamelCase). Do not use underscores as separators either.
272
273**Right:**
274```c
275PLIST_ENTRY FirstEntry;
276VOID NTAPI IopDeleteIoCompletion(PVOID ObjectBody);
277PWSTR pwszTest;
278```
279
280**Wrong:**
281```c
282PLIST_ENTRY first_entry;
283VOID NTAPI iop_delete_io_completion(PVOID objectBody);
284PWSTR pwsztest;
285```
286
2872. Avoid abbreviating function and variable names, use descriptive verbs where possible.
288
2893. Precede boolean values with meaningful verbs like "is" and "did" if possible and if it fits the usage.
290
291**Right:**
292```c
293BOOLEAN IsValid;
294BOOLEAN DidSendData;
295```
296
297**Wrong:**
298```c
299BOOLEAN Valid;
300BOOLEAN SentData;
301```
302
303## Commenting
304
3051. Avoid line-wasting comments, which could fit into a single line.
306
307**Right:**
308```c
309// This is a one-line comment
310
311/* This is a C-style comment */
312
313// This is a comment over multiple lines.
314// We don't define any strict rules for it.
315```
316
317**Wrong:**
318```c
319//
320// This comment wastes two lines
321//
322```
323
324## Null, false and 0
325
3261. The null pointer should be written as `NULL`. In the rare case that your environment recommends a different null pointer (e.g. C++11 `nullptr`), you may use this one of course. Just don't use the value `0`.
327
3282. Win32/NT Boolean values should be written as `TRUE` and `FALSE`. In the rare case that you use C/C++ `bool` variables, you should write them as `true` and `false`.
329
3303. When you need to terminate ANSI or OEM string, or check for its terminator, use `ANSI_NULL`. If the string is Unicode or Wide string, use `UNICODE_NULL`.
331
332## Notes on reformatting existing code
333
334- Never totally reformat a file and put a code change into it. Do this in separate commits.
335- If a commit only consists of formatting changes, say this clearly in the commit message by preceding it with *[FORMATTING]*.
336
337## Other points
338
339- Do not use `LARGE_INTEGER`/`ULARGE_INTEGER` unless needed for using APIs. Use `INT64`/`UINT64` instead
340- Use `#pragma once` instead of guard defines in headers
341- Don't specify a calling convention for a function unless required (usually for APIs or exported symbols)
342
343## Using an automatic code style tool
344
345TO BE ADDED BY User:Zefklop
346
347## Points deliberately left out
348
349Additional ideas were suggested during the discussion of this document, but a consensus couldn't be reached on them. Therefore we refrain from enforcing any rules on these points:
350
351- TO BE ADDED BY User:Hbelusca
352
353## See also
354
355- [Kernel Coding Style](https://reactos.org/wiki/Kernel_Coding_Style)
356- [GNU Indent](https://reactos.org/wiki/GNU_Indent)