1# curl C code style 2 3Source code that has a common style is easier to read than code that uses 4different styles in different places. It helps making the code feel like one 5single code base. Easy-to-read is an important property of code and helps 6making it easier to review when new things are added and it helps debugging 7code when developers are trying to figure out why things go wrong. A unified 8style is more important than individual contributors having their own personal 9tastes satisfied. 10 11Our C code has a few style rules. Most of them are verified and upheld by the 12`scripts/checksrc.pl` script. Invoked with `make checksrc` or even by default 13by the build system when built after `./configure --enable-debug` has been 14used. 15 16It is normally not a problem for anyone to follow the guidelines, as you just 17need to copy the style already used in the source code and there are no 18particularly unusual rules in our set of rules. 19 20We also work hard on writing code that are warning-free on all the major 21platforms and in general on as many platforms as possible. Code that obviously 22will cause warnings will not be accepted as-is. 23 24## Naming 25 26Try using a non-confusing naming scheme for your new functions and variable 27names. It does not necessarily have to mean that you should use the same as in 28other places of the code, just that the names should be logical, 29understandable and be named according to what they are used for. File-local 30functions should be made static. We like lower case names. 31 32See the [INTERNALS](https://curl.se/dev/internals.html#symbols) document on 33how we name non-exported library-global symbols. 34 35## Indenting 36 37We use only spaces for indentation, never TABs. We use two spaces for each new 38open brace. 39 40```c 41if(something_is_true) { 42 while(second_statement == fine) { 43 moo(); 44 } 45} 46``` 47 48## Comments 49 50Since we write C89 code, **//** comments are not allowed. They were not 51introduced in the C standard until C99. We use only __/* comments */__. 52 53```c 54/* this is a comment */ 55``` 56 57## Long lines 58 59Source code in curl may never be wider than 79 columns and there are two 60reasons for maintaining this even in the modern era of large and high 61resolution screens: 62 631. Narrower columns are easier to read than wide ones. There's a reason 64 newspapers have used columns for decades or centuries. 65 662. Narrower columns allow developers to easier show multiple pieces of code 67 next to each other in different windows. I often have two or three source 68 code windows next to each other on the same screen - as well as multiple 69 terminal and debugging windows. 70 71## Braces 72 73In if/while/do/for expressions, we write the open brace on the same line as 74the keyword and we then set the closing brace on the same indentation level as 75the initial keyword. Like this: 76 77```c 78if(age < 40) { 79 /* clearly a youngster */ 80} 81``` 82 83You may omit the braces if they would contain only a one-line statement: 84 85```c 86if(!x) 87 continue; 88``` 89 90For functions the opening brace should be on a separate line: 91 92```c 93int main(int argc, char **argv) 94{ 95 return 1; 96} 97``` 98 99## 'else' on the following line 100 101When adding an **else** clause to a conditional expression using braces, we 102add it on a new line after the closing brace. Like this: 103 104```c 105if(age < 40) { 106 /* clearly a youngster */ 107} 108else { 109 /* probably grumpy */ 110} 111``` 112 113## No space before parentheses 114 115When writing expressions using if/while/do/for, there shall be no space 116between the keyword and the open parenthesis. Like this: 117 118```c 119while(1) { 120 /* loop forever */ 121} 122``` 123 124## Use boolean conditions 125 126Rather than test a conditional value such as a bool against TRUE or FALSE, a 127pointer against NULL or != NULL and an int against zero or not zero in 128if/while conditions we prefer: 129 130```c 131result = do_something(); 132if(!result) { 133 /* something went wrong */ 134 return result; 135} 136``` 137 138## No assignments in conditions 139 140To increase readability and reduce complexity of conditionals, we avoid 141assigning variables within if/while conditions. We frown upon this style: 142 143```c 144if((ptr = malloc(100)) == NULL) 145 return NULL; 146``` 147 148and instead we encourage the above version to be spelled out more clearly: 149 150```c 151ptr = malloc(100); 152if(!ptr) 153 return NULL; 154``` 155 156## New block on a new line 157 158We never write multiple statements on the same source line, even for short 159if() conditions. 160 161```c 162if(a) 163 return TRUE; 164else if(b) 165 return FALSE; 166``` 167 168and NEVER: 169 170```c 171if(a) return TRUE; 172else if(b) return FALSE; 173``` 174 175## Space around operators 176 177Please use spaces on both sides of operators in C expressions. Postfix **(), 178[], ->, ., ++, --** and Unary **+, -, !, ~, &** operators excluded they should 179have no space. 180 181Examples: 182 183```c 184bla = func(); 185who = name[0]; 186age += 1; 187true = !false; 188size += -2 + 3 * (a + b); 189ptr->member = a++; 190struct.field = b--; 191ptr = &address; 192contents = *pointer; 193complement = ~bits; 194empty = (!*string) ? TRUE : FALSE; 195``` 196 197## No parentheses for return values 198 199We use the 'return' statement without extra parentheses around the value: 200 201```c 202int works(void) 203{ 204 return TRUE; 205} 206``` 207 208## Parentheses for sizeof arguments 209 210When using the sizeof operator in code, we prefer it to be written with 211parentheses around its argument: 212 213```c 214int size = sizeof(int); 215``` 216 217## Column alignment 218 219Some statements cannot be completed on a single line because the line would be 220too long, the statement too hard to read, or due to other style guidelines 221above. In such a case the statement will span multiple lines. 222 223If a continuation line is part of an expression or sub-expression then you 224should align on the appropriate column so that it's easy to tell what part of 225the statement it is. Operators should not start continuation lines. In other 226cases follow the 2-space indent guideline. Here are some examples from 227libcurl: 228 229```c 230if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) && 231 (handle->set.httpversion != CURL_HTTP_VERSION_1_0) && 232 (handle->set.httpreq == HTTPREQ_GET || 233 handle->set.httpreq == HTTPREQ_HEAD)) 234 /* did not ask for HTTP/1.0 and a GET or HEAD */ 235 return TRUE; 236``` 237 238If no parenthesis, use the default indent: 239 240```c 241data->set.http_disable_hostname_check_before_authentication = 242 (0 != va_arg(param, long)) ? TRUE : FALSE; 243``` 244 245Function invoke with an open parenthesis: 246 247```c 248if(option) { 249 result = parse_login_details(option, strlen(option), 250 (userp ? &user : NULL), 251 (passwdp ? &passwd : NULL), 252 NULL); 253} 254``` 255 256Align with the "current open" parenthesis: 257 258```c 259DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " 260 "server response left\n", 261 (int)clipamount)); 262``` 263 264## Platform dependent code 265 266Use **#ifdef HAVE_FEATURE** to do conditional code. We avoid checking for 267particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE 268shall be generated by the configure script for unix-like systems and they are 269hard-coded in the `config-[system].h` files for the others. 270 271We also encourage use of macros/functions that possibly are empty or defined 272to constants when libcurl is built without that feature, to make the code 273seamless. Like this example where the **magic()** function works differently 274depending on a build-time conditional: 275 276```c 277#ifdef HAVE_MAGIC 278void magic(int a) 279{ 280 return a + 2; 281} 282#else 283#define magic(x) 1 284#endif 285 286int content = magic(3); 287``` 288 289## No typedefed structs 290 291Use structs by all means, but do not typedef them. Use the `struct name` way 292of identifying them: 293 294```c 295struct something { 296 void *valid; 297 size_t way_to_write; 298}; 299struct something instance; 300``` 301 302**Not okay**: 303 304```c 305typedef struct { 306 void *wrong; 307 size_t way_to_write; 308} something; 309something instance; 310``` 311