Fruit's Source Code Style
Last updated 2006‒03‒02.
1. Placing braces
Braces are formatted using what looks like K&R style but is more regular. In particular, braces are put after a function declaration, not on a line of their own. So:
int main(int argc, char **argv) {
if(foo) {
bar;
baz;
}
return 0;
}
2. Using braces
If possible, braces are omitted, except when either part of an if(…) … else … uses braces, then the other part will also use braces:
if(foo) {
bar;
baz;
} else {
quux;
}
3. How to indent
Indentation is always done using tabs. It is recommended that the tab length of your editor be set to something more reasonable than 8. I personally prefer 4, but the pleasant thing about tabs is that everyone can use their favourite indentation size.
4. Using tabs
Tabs are used only at the beginning of a line. If you feel a need to align other bits, use spaces. But rather don't align them at all, unless there's a very compelling reason to do so.
5. When to indent
Control statements and their body always have lines of their own, even if they are very short:
if(x)
y();
6. Line continuation
If a line is more than 80 characters long it should really be broken into bits. Conversely, if a line is shorter, do write it on a single line. Every line but the first should be given a single extra tab. If the line is a formula the operator at which you break the line should be the first character of the new line. Examples:
x = get_foobar(foo, bar, baz) + get_xyzzy(zxnrbl, quux)
+ get_zoo(bear, monkey, lion, penguin) + get_pets(cat, dog)
+ get_colours(red, green, blue, yellow);
7. Complex line continuation
There are two reasons to deviate from this rule: if the formula is exceptionally complex it may be better to give some parts an extra tab to show that they are in fact subordinate clauses to the main formula:
y = a
+ b
+ c1
* c2
* c3
* c4
+ d;
8. Control line continuation
The other reason is when a broken line is a control statement that is followed by a body:
if(foo + bar + baz
+ quux + xyzzy) /* an extra tab */
zxnrbl();
9. Using parentheses
If possible parentheses should be omitted, except when this evokes a warning from the compiler. In particular, return and sizeof are not functions!
int x;
x = sizeof x; /* no parentheses here */
return x; /* nor here */
The only reason why sizeof often needs parentheses is that it is often used with type expressions, which need parentheses just like they do in typecasts. Where possible, apply sizeof to the variable instead of to its type though.
10. Placing parentheses
Parentheses always cuddle up to the function or control statement they follow:
if(foo) /* no space */
bar(); /* no space here either */
There shall be no spaces between the function name or the name of the control statement and the opening parenthesis.
11. Using spaces
In formulas be generous with spaces, they make things more readable:
return x * (a + b) * y;
When writing comma delimited lists, such as in function arguments, place a space only after each comma.
foo(a, b); /* good */
bar(a,b); /* bad */
bar( a , b ); /* bad */
12. Placing assignments
Avoid assignments in truth statements—if only because they often require extra parentheses to avoid compiler warnings.
r = read(fd, buf, sizeof buf);
if(r == -1)
b0rk();
13. Naming
Use lowercase names for everything, using underscores if something needs multiple words. The only exception are preprocessor constants, which are all uppercase. Short names avoid tedious typing but do make the names descriptive of their content. Don't bother reusing local variables; the compiler will do that for you.
int i, fd, program_path; /* good */
int aFile, temp; /* bad */
14. Declarations
When declaring pointers, the asterisk shall be put next to the variable name, not next to the type name. This is because the asterisk is part of what is being declared, not of the type itself. Example:
char *p; /* good, reads as “the content of p is a character” */
char* q; /* bad, “q is a character content of”?! */
The virtue of this becomes apparent when you consider:
char* p, q; /* what is the type of q? */
15. Placing declarations
Always declare new variables at the top of the function and never inside a code block:
void foo(void) {
int a; /* good */
{
int b; /* bad */
xyzzy();
}
if(frob()) {
int c; /* bad */
crunch();
}
}
If you ever get an urge to declare variables like this, it's a sign that you should split this function up into two or more smaller ones.
16. Initialization
The machine internal representation of a NULL-pointer does not have to be all-zeroes. Thus, do not initialize structures with memset() or bzero():
memset(p, 0, sizeof *p); /* bad */
const struct foo foo_0 = {0};
*p = foo_0; /* good */
17. Boolean expressions
Use the fact that boolean expressions in C mean testing for non-zero-ness. In particular, avoid pointless noise like:
if(p != NULL) …
if(i == 0) …
if(cond == FALSE) …
Even worse is:
if(broken == TRUE) …
These should be rewritten as:
if(p) …
if(!i) …
if(!cond) …
if(broken) …
… because C already does those tests implicitly.
18. Endless loops
We want to omit the test, not write a pointless one (and rely on the optimizer to get it right for us). So:
for(;;) …
And not:
while(1) …
19. Standards
Avoid using platform or compiler specific features. Write your code in ANSI C if possible and C99 otherwise.
20. Function length
Functions should be very short and to the point. They should do one thing and do it well. The name of the function should reflect this.
And finally…
…when in doubt, use your head.
— Fruit