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