• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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