Reactos
at master 356 lines 8.1 kB view raw view rendered
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)