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