Skip to topic | Skip to bottom
Home
TModeling
TModeling.LayoutGuider1.1 - 26 Jun 2008 - 16:41 - Main.guesttopic end

Start of topic | Skip to actions

Layout Guide

based on information found in the book Code Complete 2.0, chapter 31 (Layout)

Objectives: (of a good layout style)

Logical Structure

Layout accurately represents the underlying logical structure of the code

Consistency

  • A consistent style is applied in every routine, class, file, module, program, and across the entire code base.
  • Note: it's hard to read code that keeps changing style from one section to the next.

Readability

  • Easy to read and understand
  • Flows from top to bottom
  • Tokens (keywords, variables, operators, seperators) are clearly seperated from each other

Easy to modify layout

modifying one line of code shouldn't require modifying several other surrounding lines of code


Reformating

  • Don't waste time reformating working code that is reasonably readable
  • If you have to refactor (rewrite) the code for other good reasons, feel free to clean up the formating style at the same time.
    • the minimum size to consider reformatting should be at least rewriting an entire routine or larger.
  • Minor bug fixes to existing code should maintain a similar style to the code surrounding the bug fix.

White Space:

Readability

Use white space to enhance readability: spaces, tabs, line breaks, blank lines, etc.

Grouping

use white space to make sure a group of related code statements accomplishing a single task appears to be grouped together visually and separated physically from other groups (tasks).

Blank Lines

  • Use blank lines to seperate and organize your statements giving a strong indication of program layout
  • Use blank lines to divide groups of related statements into paragraphs
  • Use blank lines to separate routines from each other
  • Use blank lines to highlight comments

Indentation

  • Use indentation to show the logical structure of a program.
  • You should indent statements under the statement to which they are logically sub-ordinate. IE statements inside a loop.
  • Identation is normally accomplished via tabs or a fixed spacing (2-4 spaces per indentation).


Parenthesis:

Use parentheses to make it absolutely clear how a complex expression will be evaluated. Don't leave it up to the reader to remember how all the complex expression evaluation rules work.

   12 + 4 % 3 * 7 / 8        // Hard to figure out
becomes
   (12 + 4) % ((3*7)/8)      // Intention has been made clear via parenthesis


Layout Styles:

Block Layout

  • Use Begin-end pairs (IE braces in C/C++) to designate block boundaries
  • Interior statements inside a block should be indented from begin/end
  • Blocks which flow over several pages should have some indicator (IE comment) to allow matching of begin to end
  • Use a consistent visual layout for all blocks in C/C++
  • Any block layout is fine, pick one style and stick with it for the all code for the entire team.

    // Block Style #1
    if ( expression ) {
       ... do something
    } else {
       ... do something else
    }

    vs.

    // Block Style #2
    if ( expression )
    {
       ... do something
    }
    else
    {
       ... do something else
    }

    vs.

    // Block Style #3
    if ( expression )
      {
      ... do something
      }
    else
      {
      ... do something else
      }

    Note:  Avoid double indentation of interior statements with this strategy

    vs.

    // Style #4 (Endline style, common in VB, not so common in C++)
    if (<condition>) then
                          ... do something
                     else
                          ... do something else (several pages)
                     end if

    Note: Endline style can be useful in C/C++ for routine calls with large parameter lists
    For Example:
       DWORD dwStyle = MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
       iResult = MultiByteToWideChar( cpSrc, dwStyle,
                                      pszSrc, cchLen,
                                      pszWide, cchLen );

Format single statement (S-S) blocks consistently

  • A control structure with a single statement
  • Any single statement block layout is fine, pick one style and stick with it.

     // S-S Style # 1
     if ( expression )
        single-statement

     // S-S Style # 1A
     if ( expression ) single-statement

     // S-S Style # 1B
     if ( expression ) { single-statement }

     // S-S Style #2
     if ( expression ) {
        single-statement
     }

     // S-S Style #3
     if ( expression )
     {
        single-statement
     }

     // S-S Style #4
     if ( expression )
        {
        single-statement
        }

For complicated expressions, put separate conditions on separate lines

    if ( ((test1) && (test2)) ||
         ((test3) && (test4)) ||
         ((test5) && (test6)) )
       ...

GOTO's:

  • Strategy #1, just avoid using Goto's completely
  • Strategy #2, only allow goto's to help avoid deeply nested error handling statement hierarchies when resource cleanup is needed
  • goto LABEL should be in all caps
  • put the goto statement on a single line all by itself, for high visibility.
  • put goto LABEL on a line all by itself, for high visibility.

Example:
    bTest = AllocResourceAndComplicatedProcess()
    if (!bTest) {
        goto LABEL_CLEANUP;
    }

LABEL_CLEANUP:
    if (!bTest)
    {
       // Cleanup resource code goes here
    }


Individual Statement Layout

Statement Length

  • Lines longer than 80 characters are hard to read
  • using 80-character lines consistently discourages deep nesting
  • Lines longer than 80 characters don't print properly on most printers

Use Spaces for clarity

  • Use spaces to make logical expression more readable
  • Use spaces to make array references readable
  • Use spaces to make function arguments readable

Formatting continuation lines

  • Make incompleteness of each line fragment obvious
    if ((long test 1) &&
        (long test 2))

    or

    if ((long test 1)
       && (long test 2))
  • Keep closely related elements together
  • Indent function call continuation lines a standard amount (alternately, line up all continuation lines under first argument)
  • Make it easy to find the end of a continuation line
  • Indent control statement continuation lines the standard amount (alternately, line up all continuation lines under first condition)
  • Indent assignment continuation lines the standard amount (alternately, line up all continuation lines under first term)

Do not waste time aligning right sides of multiple assignment statements

Don't do this, this takes to much time to create and maintain
      xyz     = expression 1;
      xyzLong = expression 2;

Do this instead.
      xyz = expression1;
      xyzLong = expression2;

Avoid Multiple statements on one line

  • Multiple statements decreases readability
  • Have to read top to bottom and then left to right instead of just top to bottom.
  • Makes it harder to track down bugs to actual problems (which statement on line is the culprit)
  • More work to maintain interior statements on multi-line.
  • Avoid Multiple operations per line, IE, avoid complex side-effects (hidden statements)
// Don't do this
      PrintMessage( ++n, n+2 );
// Do this instead
       ++n;
       PrintMessage( n, n+2 );


Data Declarations:

Use only one data declaration per line

Declare variables close to where they are first used

helps reader not have to jump around code to find declarations

Order declarations sensibly

  • Group by similar types or by similar tasks
  • No need to sort alphabetically
  • For pointers, Put pointer asterisk next to variable name
       EmployeeList *employees;
  • For pointers, Better yet, use a typedef to eliminate need for asterisk
       typedef EmployeeList * EmployeeListPtr;
       EmployeeListPtr employees;


Comments:

See Comment Guide for more detailed info

Indent Comments

in parrallel with the code blocks that they describe and are associated with

Seperate comments from other lines of code

with at least one blank line


Routines: (Functions/Procedures/Methods)

  • Use blank lines to separate parts of a routine
  • use standard indentation for routine arguments (alternately, use endline indentation)
  • Routine comment header blocks should be kept brief and functional
  • Routine header blocks help with grouping and readablility

/*--------------------------------------------
  Name:  PrintMessage()
  Desc:  used for outputing messages to user
--------------------------------------------*/

void PrintMessage( ... )
{
...
}

Classes:

Suggested Class Interface Layout

  • Header block comment
  • Constructors/destructor's
  • Public Routines
  • Protected routines
  • Private routines
  • Member data (fields)

Suggested Class Implementation Layout

  • Header comment
  • Class Data
  • Public routines
  • Protected routines
  • Private routines

Identify each class clearly in file

Multiple classes should be clearly separated from each other

Avoid overemphasizing separating comments within classes


Files/Programs:

Put one class in one file

Give the file a name closely related to the class name

Separate routines within a file clearly

  • using blank lines
  • using brief function header blocks

Order the source file consistently

Suggested Layout (include file):

  • File Header block (describes include file)
  • Include Files
  • Constant definitions (for more than one class)
  • Enumerations (more than one class)
  • Macro function definitions (Compiler flags)
  • Type Definitions (more than one class) Note: includes lightweight structures
  • imported Global variables (and imported function declarations)
  • exported Global variables (and exported function declarations)
  • Classes (and heavy weight structures)

Suggested Layout (source file):

  • File Header block (describes source file)
  • Include Files
  • Global Variables (static)
  • Local Constant definitions
  • Local Enumerations
  • Local Macro function definitions
  • Local Type Definitions
  • Local global variables
  • Local Function Declarations
  • Local Classes
  • Function/Method Definitions (Global)
  • Function/Method Definitions (Local)

-- ShawnDB - 18 Jun 2008
to top


You are here: TModeling > Software > CodeGuide > StyleGuide > LayoutGuide

to top

Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback