Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

What does style look like, part 3

What does style look like, part 3

  • Comments 25

When we last left the code we were looking at, it looked like:

#include "list.h"
main(C cArg, SZ rgszArg[]) {
    I iNode, cNodes = atoi(rgszArg[1]), cNodesToSkip = atoi(rgszArg[2]);
    PNODE pnodeT, pnodeCur;
    InitNodes(cNodes);
    for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++) {
        pnodeT = PnodeNew(i);
        InsertNext(pnodeCur, pnodeT);
        pnodeCur = pnodeT;
    }
    while (pnodeCur != PnodeNext(x)) {
        for (iNode = 1; iNode < cNodesToSkip ; iNode++)
            pnodeCur = PnodeNext(pnodeCur);
        FreeNode(PnodeDeleteNext(pnodeCur));
    }
    printf("%d\n", Item(nodeCur));
}

This time, let's consider a different indentation style:  Braces after the expression, every optional brace included (modified BSD)

#include "list.h"
main(C cArg, SZ rgszArg[])
{
    I iNode, cNodes = atoi(rgszArg[1]), cNodesToSkip = atoi(rgszArg[2]);
    PNODE pnodeT, pnodeCur;
    InitNodes(cNodes);
    for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++)
    {
        pnodeT = PnodeNew(i);
        InsertNext(pnodeCur, pnodeT);
        pnodeCur = pnodeT;
    }
    while (pnodeCur != PnodeNext(x))
    {
        for (iNode = 1; iNode < cNodesToSkip ; iNode++)
        {
            pnodeCur = PnodeNext(pnodeCur);
        }
        FreeNode(PnodeDeleteNext(pnodeCur));
    }
    printf("%d\n", Item(nodeCur));
}

That's a fascinating difference.  Moving the braces down to the next line opens the code up quite a bit, making it easier to see how the code is structured.  Next, what happens with the declarations - the declaration of iNode,cNodes, and cNodesToSkip is smushed together, lets split them out into separate lines.

#include "list.h"
main(C cArg, SZ rgszArg[])
{
    I iNode;
    I cNodes = atoi(rgszArg[1]);
    I cNodesToSkip = atoi(rgszArg[2]);
    PNODE pnodeT;
    PNODE pnodeCur;
    InitNodes(cNodes);
    for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++)
    {
        pnodeT = PnodeNew(i);
        InsertNext(pnodeCur, pnodeT);
        pnodeCur = pnodeT;
    }
    while (pnodeCur != PnodeNext(x))
    {
        for (iNode = 1; iNode < cNodesToSkip ; iNode++)
        {
            pnodeCur = PnodeNext(pnodeCur);
        }
        FreeNode(PnodeDeleteNext(pnodeCur));
    }
    printf("%d\n", Item(nodeCur));
}

Again, this helps a bit, but not a lot.  What about other bracing styles?

#include "list.h"
main(C cArg, SZ rgszArg[])
{
        I iNode;
        I cNodes = atoi(rgszArg[1]);
        I cNodesToSkip = atoi(rgszArg[2]);
        PNODE pnodeT;
        PNODE pnodeCur;
        InitNodes(cNodes);
        for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++)
        {
                pnodeT = PnodeNew(i);
                InsertNext(pnodeCur, pnodeT);
                pnodeCur = pnodeT;
        }
        while (pnodeCur != PnodeNext(x))
        {
                for (iNode = 1; iNode < cNodesToSkip ; iNode++)
                {
                        pnodeCur = PnodeNext(pnodeCur);
                }
                FreeNode(PnodeDeleteNext(pnodeCur));
        }
        printf("%d\n", Item(nodeCur));
}

8 character indents stretch the code out a bunch, but they don't effect the overall effect.  How about a variant of 8 char indents?

#include "list.h"
main(C cArg, SZ rgszArg[])
    {
        I iNode;
        I cNodes = atoi(rgszArg[1]);
        I cNodesToSkip = atoi(rgszArg[2]);
        PNODE pnodeT;
        PNODE pnodeCur;
        InitNodes(cNodes);
        for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++)
            {
                pnodeT = PnodeNew(i);
                InsertNext(pnodeCur, pnodeT);
                pnodeCur = pnodeT;
            }
        while (pnodeCur != PnodeNext(x))
            {
                for (iNode = 1; iNode < cNodesToSkip ; iNode++)
                    {
                        pnodeCur = PnodeNext(pnodeCur);
                    }
                FreeNode(PnodeDeleteNext(pnodeCur));
            }
        printf("%d\n", Item(nodeCur));
    }

This one's kinda interesting.  The braces are now more clearly laid out.  On the other hand, it's a bit disconcerting to have the "printf" hanging out on its own.  Personally, I'm not too happy with this one.

How about the "braces appear on the same line as the code they wrap"?

#include "list.h"
main(C cArg, SZ rgszArg[])
{
    I iNode;
    I cNodes = atoi(rgszArg[1]);
    I cNodesToSkip = atoi(rgszArg[2]);
    PNODE pnodeT;
    PNODE pnodeCur;
    InitNodes(cNodes);
    for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++)
        {
        pnodeT = PnodeNew(i);
        InsertNext(pnodeCur, pnodeT);
        pnodeCur = pnodeT;
        }
    while (pnodeCur != PnodeNext(x))
        {
        for (iNode = 1; iNode < cNodesToSkip ; iNode++)
            {
            pnodeCur = PnodeNext(pnodeCur);
            }
        FreeNode(PnodeDeleteNext(pnodeCur));
        }
    printf("%d\n", Item(nodeCur));
}

An interesting variant.  I don't know if it's an improvement, but...

Just for grins, the style of a senior developer within Microsoft:

#include "list.h"
main(C cArg, SZ rgszArg[])
{
    I iNode;
    I cNodes = atoi(rgszArg[1]);
    I cNodesToSkip = atoi(rgszArg[2]);
    PNODE pnodeT;
    PNODE pnodeCur;
    InitNodes(cNodes);
    for (iNode = 2, pnodeCur = PnodeNew(1); iNode <= cNodes ; iNode++) {
        pnodeT = PnodeNew(i);
        InsertNext(pnodeCur, pnodeT);
        pnodeCur = pnodeT;
        }
    while (pnodeCur != PnodeNext(x)) {
        for (iNode = 1; iNode < cNodesToSkip ; iNode++) {
            pnodeCur = PnodeNext(pnodeCur);
            }
        FreeNode(PnodeDeleteNext(pnodeCur));
        }
    printf("%d\n", Item(nodeCur));
    }

In this style, the opening brace goes with the if/while/for loop, but the closing brace goes with the code at that level of indentation.  Again, it's an "interesting" choice.

Tomorrow, we add comments.  That'll help a bundle towards helping this out.

 

  • Of those, my style is most like your modified BSD style.

    For instance (pardon my Java... I've got it on the brain at the moment..):

    import javax.swing.*;

    public class Sample
    {
    public Sample ()
    {
    // Blah blah blah
    }

    public static void main ( String[] args )
    {
    for ( int i = 0; i < args.length; i++ )
    {
    System.out.println ( args[ i ] );
    }
    }
    }

    I'm all about the white space. I think it makes my code easy to read. Also, notice that in Java I used the square array brackets on the variable type, and not the name. To me, this helps me know that much faster that I'm dealing with an array.

    The only other "real" language I know is C, and my style is almost identical.

    The only problem is that when I have to hand in assignments (Still a student), this style takes up a LOT of paper and sometimes is butchered by print margins.
  • "braces appear on the same line as the code they wrap" is the only way to fly. Not indenting the braces is ok too, but it's just not the style I use or am used to.

    Having the opening brace on the same line as the if/for/while is definitely worse because when you're looking at a } it's *much* harder to quickly scan the code and find the matching {. Sure, you can hit ^] in VC to find it, but you don't always have VC at your disposal.

    Having each { and } on its own line also gives some much-needed vertical whitespace. There's nothing I hate more than seeing a big ol' block of code with no vertical spacing to indicate logical breaks in the logic flow.
  • Funny you should mention that Bjorn, that change comes up during the comments discussion tomorrow :)
  • Agreed. I would also punch a newline after the for- and while-blocks to make them stand out further.
  • My style is 'modified BSD' -- as other readers suggest, it gives you more vertical white space (I would put another one blank like after variables' declarations)...
  • You're all wimps with this structured code. Surveycraft is basic pseudocode (as real survercraft variables are names after the line number created on)

    10 10=input "enter something"

    20 20=input "enter something"

    30 msgbox 10

    40 msgbox 20

    50

    15 If 10 = "dog" then goto 30

    35 If 20 = "" then goto 50


    Now this is real coding style. Seperating actions from flow. Makes C coding style debates seem really minor. Lucky it has gone out of fashion.
  • BTW, it's not legal in either C++ or C99 to leave out the 'int' return type for main (though it is legal to omit 'return')...
  • You're right Skywing, but that's the sample as it appears in the book, so...
  • Mine's 'modified BSD', but I normally put a blank line before a new control structure (unless right after an opening brace), after closing a control structure (unless right before a closing brace), and between declarations and code, so I'd insert a blank line after line 1, 8, 9, 15, 21 and 23 (of your third example, where you put each declaration on its own line).

    This style really emphasises control structure. I also put spaces inside parentheses unless the parens indicate a cast. In C languages, I always put a space between a control keyword and the controlled expression but never between a function call and its parameter list [e.g. if ( x ) but f( x )]. OK, it takes a lot of lines - and I follow the rule of not allowing a function to take more than a couple of screenfuls, but then a screenful is a lot of lines on current monitors. Personally I can't stand horizontal scrolling; if I must break a function call, for example, I'll normally break after the opening paren and after every argument (i.e. either all-on-one-line or one-argument-per-line).
  • OK, I figured we could ask the 'K' of K&R and maybe get a deep response.
    -------------------
    From: Brian Kernighan
    Sent: Thursday, November 11, 2004 5:58 PM
    To: Michael
    Subject: Re: Braces, indention, etc.

    i just copied what ken and dennis did, if i remember right. nothing very deep.
    -------------------
    OK, nothing good there. I'll see if I can get Ken to offer up something...
  • > Just for grins, the style of a senior
    > developer within Microsoft

    Are you sure he indented by 4 columns not 3?

    IBM PL/I manuals put the "DO;" at the end of a line as in OTBS, but indented the "END;" at the same level as the nested statements instead of outdenting it back to the "IF" or "WHILE" or whatever initiated the do-group. If I recall correctly, those same IBM PL/I manuals indented code by multiples of 3 columns. (And oh yeah, don't forget to leave 1 blank in column 1 of every line unless you're going to submit a compile listing to the International Obfuscated PL/I Coding Contest.)

    Unfortunately I don't know MULTICS PL/I style. Can anyone else say?
  • I'm pretty sure it was 4 (although I may be wrong, I'm resurrecting his style from memory, the code he worked on no longer displays this style). To my knowledge, this developer never worked in PL/I.

    Ah, found some code that hadn't been "cleaned" up. Yup, it was 4.
  • I've seen some style guides (SGI?) that specify #1 for control structures but #2 for functions.

    The most unique style I ever had to match was:

    if(condition){
    doSomething();
    }
    else{
    doSomethingElse();
    }

    It wasn't hard to pick up given a K&R background, but it looked very strange the first time I saw it.
  • I vote for modified BSD or the one following "lets split them (the declarations) out into separate lines." Opening up the code, like you say, makes it easier to see what's going on with a glance, rather than having to read it. This reason (glance vs. read) is why I like languages with C-style syntax over languanges with VB-style syntax. It's just easier to see what's going on.
  • Greg, you're confusing the content with the style. The content is irrelevant, it's the style that counts.

    Maybe I should have written up a function that did absolutely nothing, but for better or for worse, I chose a real example.
Page 1 of 2 (25 items) 12