MFC Programmer's SourceBook : Thinking in C++
Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

Parens, braces and indentation

You may notice the formatting style in this book is different from many traditional C styles. Of course, everyone feels their own style is the most rational. However, the style used here has a simple logic behind it, which will be presented here mixed in with ideas on why some of the other styles developed.

The formatting style is motivated by one thing: presentation, both in print and in live seminars. You may feel your needs are different because you don’t make a lot of presentations, but working code is read much more than it is written, so it should be easy for the reader to perceive. My two most important criteria are “scannability” (how easy it is for the reader to grasp the meaning of a single line) and the number of lines that can fit on a page. This latter may sound funny, but when you are giving a live presentation, it’s very distracting to shuffle back and forth between slides, and a few wasted lines can cause this.

Everyone seems to agree that code inside braces should be indented. What people don’t agree on, and the place where there’s the most inconsistency within formatting styles is this: where does the opening brace go? This one question, I feel, is what causes such inconsistencies among coding styles (For an enumeration of coding styles, see C++ Programming Guidelines, by Tom Plum & Dan Saks, Plum Hall 1991). I’ll try to convince you that many of today’s coding styles come from pre-Standard C constraints (before function prototypes) and are thus inappropriate now.

First, my answer to the question: the opening brace should always go on the same line as the “precursor” (by which I mean “whatever the body is about: a class, function, object definition, if statement, etc.”). This is a single, consistent rule I apply to all the code I write, and it makes formatting much simpler. It makes the “scannability” easier – when you look at this line:

void func(int a);

you know, by the semicolon at the end of the line, that this is a declaration and it goes no further, but when you see the line:

void func(int a) {

you immediately know it’s a definition because the line finishes with an opening brace, and not a semicolon. Similarly, for a class:

class Thing;

is a class name declaration, and

class Thing {

is a class declaration. You can tell by looking at the single line in all cases whether it’s a declaration or definition. And of course, putting the opening brace on the same line, instead of a line by itself, allows you to fit more lines on a page.

So why do we have so many other styles? In particular, you’ll notice that most people create classes following the above style (which Stroustrup uses in all editions of his book The C++ Programming Language from Addison-Wesley) but create function definitions by putting the opening brace on a single line by itself (which also engenders many different indentation styles). Stroustrup does this except for short inline functions. With the approach I describe here, everything is consistent – you name whatever it is ( class, function, enum, etc) and on that same line you put the opening brace to indicate that the body for this thing is about to follow. Also, the opening brace is the same for short inlines and ordinary function definitions.

I assert that the style of function definition used by many folks comes from pre-function-prototyping C, where you had to say:

void bar()
 int x;
 float y;
{
 /* body here */
}

Here, it would be quite ungainly to put the opening brace on the same line, so no one did it. However, they did make various decisions about whether the braces should be indented with the body of the code, or whether they should be at the level of the “precursor.” Thus we got many different formatting styles.

There are other arguments for putting for placing the brace on the line immediately following the declaration (of a class, struct, function, etc.). The following came from a reader, and are presented here so you know what the issues are:

Experienced ‘vi’ (vim) users know that typing the ‘]’ key twice will take the user to the next occurance of ‘{‘ (or ^L) in column 0. This feature is extremely useful in navigating code (jumping to the next function or class definition). [ My comment: when I was initially working under Unix, Gnu emacs was just appearing and I became enmeshed in that. As a result, ‘vi’ has never made sense to me, and thus I do not think in terms of “column 0 locations.” However, there is a fair contingent of ‘vi’ users out there, and they are affected by this issue]

Placing the ‘{‘ on the next line eliminates some confusing code in complex conditionals, aiding in the scannability. Example:

if(cond1
   && cond2
   && cond3) {
   statement;
}

The above [asserts the reader] has poor scannability. However,

if (cond1
&& cond2
&& cond3
{
statement;
}

breaks up the ‘if’ from the body, resulting in better readability.

Finally, it’s much easier to visually align braces when they are aligned in the same column. They visually "stick out" much better. [ End of reader comment ]

The issue of where to put the opening curly brace is probably the most discordant issue. I’ve learned to scan both forms, and in the end it comes down to what you’ve grown comfortable with. However, I note that the official Java coding standard (found on Sun’s Java Web site) is effectively the same as the one I present here – since more folks are programming in both languages, the consistency between coding styles may be helpful.

The approach I use removes all the exceptions and special cases, and logically produces a single style of indentation, as well. Even within a function body, the consistency holds, as in:

for(int i = 0; i < 100; i++) {
  cout << i << endl;
  cout << x * i << endl;
}

The style is very easy to teach and remember – you use a single, consistent rule for all your formatting, not one for classes, one for functions and possibly others for for loops, if statements, etc. The consistency alone, I feel, makes it worthy of consideration. Above all, C++ is a new language and (although we must make many concessions to C) we shouldn’t be carrying too many artifacts with us that cause problems in the future. Small problems multiplied by many lines of code become big problems. (For a thorough examination of the subject, albeit in C, see David Straker: C Style: Standards and Guidelines, Prentice-Hall 1992).

The other constraint I must work under is the line width, since the book has a limitation of 50 characters. What happens when something is too long to fit on one line? Well, again I strive to have a consistent policy for the way lines are broken up, so they can be easily viewed. As long as something is all part of a single definition, it should ...

Contents | Prev | Next


Go to CodeGuru.com
Contact: webmaster@codeguru.com
© Copyright 1997-1999 CodeGuru