syque.com

The Psychology of Quality and More

| Menu | Books | Share | Search | Settings |

C Style: Standards and Guidelines (contents)

CHAPTER 6 : Layout

PART 3 : LAYOUT

CHAPTER 6 : Code Layout
6.1 Basic principles of code layout
6.2 Use of Spaces
6.3 Use of blank lines
6.4 Use vertical alignment
6.5 Indentation level
6.6 Line wrapping
6.7 Braces
6.8 Use of parentheses
6.9 Nested single statement
6.10 Empty statements
6.11 'else..if'
6.12 'switch' statements
6.13 'do..while'
6.14 Labels
6.15 Data declarations
6.16 Function declaration
6.17 Preprocessor commands
6.18 Summary

<--Prev page | Next page -->

 

6.6  Line wrapping

Wrapping of lines occurs when a single statement is continued onto the following line. There are a number of strategies for handling this, which are discussed below.

6.6.1  Basic considerations of wrapping

The simplest way to wrap a line is to continue it from column 1 on the following line:

 

     VehicleAccessCode + VersionStamp / (AccessCorrectionFactor +
ReadPassword());

-------------------------------------------------------------------------

This is clearly a continuation of the previous line, but it ruins the line of the indentation, reducing the legibility of the code. We should at least indent the continuation to the current level of nesting:

 

     VehicleAccessCode + VersionStamp / (AccessCorrectionFactor +
     ReadPassword());

 

The problem with this example is that the continuation line now looks like a separate statement. It is only by carefully looking right to the end of the previous line that it is clear that this is actually a continuation. This may be addressed by indenting the continuation line still further:

 

     VehicleAccessCode + VersionStamp / (AccessCorrectionFactor +
         ReadPassword());

 

The continuation is now much clearer. Individual cases of wrapping have differences which may require varying approaches. These are dealt with in individual sections, below.

6.6.2  Wrapping expressions

Consider again the previous example:

 

VehicleAccessCode + VersionStamp / (AccessCorrectionFactor +
     ReadPassword());

 

Putting the operator at the end of the line flags that this line is to be continued on the following line, in the same manner as a hyphen in written English. However, if the reader misses this, as can happen to things on the right, the following line can appear to be a new statement, despite the indentation. This can be avoided by putting the operator at the start of the continuation line. This also follows the way an expression is read aloud: "First number," pause, "plus second number." However, this is done at the cost of possible confusion now on the first line, where only the lack of a semicolon indicates that the line is to be continued. This is one of those contentious points which must be resolved, one way or the other. We will continue with the operator on the continuation line:

 

VehicleAccessCode + VersionStamp / (AccessCorrectionFactor
    + ReadPassword());

 

Rather than split the expression at the last possible point, the expression can be made more readable by looking for a point beforehand where the line can split into logical chunks. One way to help this is to try to keep matching parentheses on the same line:

 

VehicleAccessCode + VersionStamp
    / (AccessCorrectionFactor + ReadPassword());

 

Note, however, the danger with the above example - the first line may be taken as being the whole numerator of the expression. Items on the same line have a closer association, which allows us to use the rules of precedence to help make the expression clearer. In this case it means wrapping at the '+', which is at a lower precedence than the '/':

 

VehicleAccessCode
    + VersionStamp / (AccessCorrectionFactor + ReadPassword());

 

Now, most of the code is on the continuation line and could end up requiring wrapping again. The bottom line is, as always, to think of the reader. When a clear solution to a layout problem is not apparent, the most readable compromise should be chosen.

6.6.3  Wrapping parenthesized expressions

Expressions that use a deep levels of nesting can become very complex and difficult to understand, even using spacing and parentheses and line-wrapping rules, as discussed above.

 

if ( ( (Ch >= MinCh) && (Ch <= MaxCh) ) || ( (Ch == NullCh) &&
    ((PrevCh >= MinCh) && (PrevCh <= MaxCh)) ) )

 

This is almost like a small program, and can be similarly broken down into chunks that can be understood on an individual basis by treating parentheses as braces, and vertically aligning those that do not have a matching partner on the same line. Nested expressions at the same level are indented to the same column:

 

if  (   (   (Ch >= MinCh)             /* if within normal range   */
         && (Ch <= MaxCh)
        )
     ||
        (   (Ch == NullCh)            /* ..or is null..       */
         && (   (PrevCh >= MinCh)     /* ..and previous char..     */
             && (PrevCh <= MaxCh)     /* ..is within normal range */
            )
        )
    )

 

This is at some cost in vertical space, and may even become less readable. Space can be saved by increasing the size of the 'chunk' on each line, particularly where is performs a clear single action, such as an in-bounds check. Also, the lone parentheses on the last few lines may be considered undesirable, especially as the nesting can be seen from the indentation. A vertically more conservative version is:

 

if ( ((Ch >= MinCh) && (Ch <= MaxCh))
        || ( (Ch == NullCh)
            && ((PrevCh >= MinCh) && (PrevCh <= MaxCh)) ) )

 

6.6.4  Wrapping assignments

In an assignment, the equals sign divides the left and right hand sides into separate parts. Thus when wrapping the right hand side, it makes sense that the continuation should also be to the right of the equals sign. Note that this is a case where a 'toothbrush' layout may be preferable to a 'comb':

 

Heading.Parameter = Heading.StdWidth + Heading.IncrementSize
                        + IncrementFactor( Heading );

 

6.6.5  Wrapping conditional expressions

Conditional expressions may form an abbreviation for an if..else statement. Thus:

 

WidgetStyle = (FlangeShape == FS_CURVED) ? WIDGET_GOTHIC : WIDGET_ROMAN;

 

..is an abbreviation of..

 

if ( FlangeShape == FS_CURVED )
    WidgetStyle = WIDGET_GOTHIC;
else
    WidgetStyle = WIDGET_ROMAN;

 

This can be used to improve the layout of the conditional expression. It can even be used when wrapping is not necessary, as it better follows the 'one action per line' principle:

 

WidgetStyle =   ( FlangeShape == FS_CURVED )
                ? WIDGET_GOTHIC
                : WIDGET_ROMAN;

 

6.6.6  Wrapping 'for' statements

The for statement can become long, particularly if there are several initializing or loop statements, or if the expressions are complex:

 

for ( FlangeNo = FIRST_FLANGE_NO;  (FlangeNo > MIN_FLANGE_NO)
        && (FlangeNo < MAX_FLANGE_NO); FlangeNo = GetNextFlangeNo() )

 

The 'one action per line' principle can be invoked to break the line at the semicolons:

 

for ( FlangeNo = FIRST_FLANGE_NO;
        (FlangeNo > MIN_FLANGE_NO) && (FlangeNo < MAX_FLANGE_NO);
        FlangeNo = GetNextFlangeNo() )

 

Note that the continuation lines are indented past the initial parenthesis. If the expressions wrap, then three stages may be made clearer by using further indents:

 

for (   FlangeNo = FIRST_FLANGE_NO,
            WidgetNo = FIRST_WIDGET_NO;
        (FlangeNo > MIN_FLANGE_NO)
            && (FlangeNo < MAX_FLANGE_NO);
        FlangeNo = GetNextFlangeNo(),
            WidgetNo++ )

 

6.6.7  Wrapping function calls

Function calls often wrap when they include expressions as parameters or have multiple parameters. The function name can be made clearer by using a 'toothbrush' layout, indenting the wrapping of its parameters past the initial parenthesis:

 

CreateTitle( *MainTitle, *SecondaryTitle, UserText.Abstract,
                Patterns.PlainBorder );

 

A alternative is to put one parameter per line, vertically aligned. This may be clearer, and allows commenting of each parameter, helping the reader to understand a complex call:

 

CreateTitle(    *MainTitle,               /* big, centered        */
                *SecondaryTitle,      /* smaller, underneath  */
                UserText.Abstract,        /* boxed, at bottom     */
                Patterns.PlainBorder );   /* simple page border   */

 

<--Prev page | Next page -->

 

Site Menu

| Home | Top | Settings |

Quality: | Quality Toolbook | Tools of the Trade | Improvement Encyclopedia | Quality Articles | Being Creative | Being Persuasive |

And: | C Style (Book) | Stories | Articles | Bookstore | My Photos | About | Contact |

Settings: | Computer layout | Mobile layout | Small font | Medium font | Large font | Translate |

 

You can buy books here

More Kindle books:

And the big
paperback book


Look inside

 

Please help and share:

 

| Home | Top | Menu |

© Changing Works 2002-
Massive Content -- Maximum Speed