• 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 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
12lib/checksrc.pl script. Invoked with `make checksrc` or even by default by the
13build 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 document on how we name non-exported library-global symbols.
32
33## Indenting
34
35We use only spaces for indentation, never TABs. We use two spaces for each new
36open brace.
37
38    if(something_is_true) {
39      while(second_statement == fine) {
40        moo();
41      }
42    }
43
44## Comments
45
46Since we write C89 code, `//` comments are not allowed. They weren't
47introduced in the C standard until C99. We use only `/*` and `*/` comments:
48
49    /* this is a comment */
50
51## Long lines
52
53Source code in curl may never be wider than 80 columns and there are two
54reasons for maintaining this even in the modern era of very large and high
55resolution screens:
56
571. Narrower columns are easier to read than very wide ones. There's a reason
58   newspapers have used columns for decades or centuries.
59
602. Narrower columns allow developers to easier show multiple pieces of code
61   next to each other in different windows. I often have two or three source
62   code windows next to each other on the same screen - as well as multiple
63   terminal and debugging windows.
64
65## Braces
66
67In if/while/do/for expressions, we write the open brace on the same line as
68the keyword and we then set the closing brace on the same indentation level as
69the initial keyword. Like this:
70
71    if(age < 40) {
72      /* clearly a youngster */
73    }
74
75When we write functions however, the opening brace should be in the first
76column of the first line:
77
78    int main(int argc, char **argv)
79    {
80      return 1;
81    }
82
83## 'else' on the following line
84
85When adding an `else` clause to a conditional expression using braces, we add
86it on a new line after the closing brace. Like this:
87
88    if(age < 40) {
89      /* clearly a youngster */
90    }
91    else {
92      /* probably grumpy */
93    }
94
95## No space before parentheses
96
97When writing expressions using if/while/do/for, there shall be no space
98between the keyword and the open parenthesis. Like this:
99
100    while(1) {
101      /* loop forever */
102    }
103
104## Use boolean conditions
105
106Rather than test a conditional value such as a bool against TRUE or FALSE, a
107pointer against NULL or != NULL and an int against zero or not zero in
108if/while conditions we prefer:
109
110    result = do_something();
111    if(!result) {
112      /* something went wrong */
113      return result;
114    }
115
116## No assignments in conditions
117
118To increase readability and reduce complexity of conditionals, we avoid
119assigning variables within if/while conditions. We frown upon this style:
120
121    if((ptr = malloc(100)) == NULL)
122      return NULL;
123
124and instead we encourage the above version to be spelled out more clearly:
125
126    ptr = malloc(100);
127    if(!ptr)
128      return NULL;
129
130## New block on a new line
131
132We never write multiple statements on the same source line, even for very
133short if() conditions.
134
135    if(a)
136      return TRUE;
137    else if(b)
138      return FALSE;
139
140and NEVER:
141
142    if(a) return TRUE;
143    else if(b) return FALSE;
144
145## Space around operators
146
147Please use spaces on both sides of operators in C expressions.  Postfix `(),
148[], ->, ., ++, --` and Unary `+, - !, ~, &` operators excluded they should
149have no space.
150
151Examples:
152
153    bla = func();
154    who = name[0];
155    age += 1;
156    true = !false;
157    size += -2 + 3 * (a + b);
158    ptr->member = a++;
159    struct.field = b--;
160    ptr = &address;
161    contents = *pointer;
162    complement = ~bits;
163    empty = (!*string) ? TRUE : FALSE;
164
165## Platform dependent code
166
167Use `#ifdef HAVE_FEATURE` to do conditional code. We avoid checking for
168particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE
169shall be generated by the configure script for unix-like systems and they are
170hard-coded in the config-[system].h files for the others.
171
172We also encourage use of macros/functions that possibly are empty or defined
173to constants when libcurl is built without that feature, to make the code
174seamless. Like this style where the `magic()` function works differently
175depending on a build-time conditional:
176
177    #ifdef HAVE_MAGIC
178    void magic(int a)
179    {
180      return a + 2;
181    }
182    #else
183    #define magic(x) 1
184    #endif
185
186    int content = magic(3);
187