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

Back to the index page