Solutions for Developers, Services for Companies, Software for Users
 



bottrap link

A blog is now available Here.

Interested in becoming an Affiliate and earning 25% of all generated sales?  Click Here.

Handmade Art and
Treasures!

Handmade Art and Treasures: Fannys Follies

25% off for first-time customers at VistaPrint!

 

  

The importance of a coding standard and the benefits of adhering to it

By James R. Twine (Copyright 2001-2003, James R. Twine)

[Previous Article In Segment] [Next Article In Segment]

Introduction

Coding standards are important for many reasons.  First and foremost, they specify a common format for the source code and comments.  This allows developers to easily share code, and the ideas expressed within the code and comments, between each other.  It also specifies how comments (internal documentation) should be handled.  More importantly, a well designed standard will also detail how certain code should be written, not just how it looks on screen.

More important than the reasons for having a standard is actually adhering to it consistently.  Having a coding standard documented and available means nothing if developers are not using it consistently.  If that becomes the case, it is no longer a coding standard, it has become a coding suggestion.  Worse yet are the developers that do not have a style or standard at all, and think that their lack of a style/standard IS a coding style/standard!
 

Coding Standards vs. Coding Styles

Most coding standards that I have encountered are little more than coding style documents.  What is the difference?  A coding style specifies things like how you indent, tabs vs. spaces, use of "reverse-Hungarian" notation for naming of variables, etc.  A coding standard often includes a coding style, but goes beyond just how to name a variable: it tells you how that variable should be treated and when it should (and should not be) used.

Take as an example the following snippet of code.  The code performs a stupid swap trick to show the usefulness of comments and a style.  This code adheres to the JRTwine Software, LLC coding standards.  Elements of coding style are colored in cyan, and elements of the coding standard are colored in green.  Specific points in this example will be covered below.

DWORD CSomeClass::SafeReadFileAndSwaB( HANDLE hFile, BYTE btaBuffer[], DWORD &dwBufLen )
{
    if( ( !hFile ) || ( hFile == INVALID_HANDLE_VALUE ) ||     // If Any Parameters Invalid
        ( !caBuffer ) || ( dwBufLen < 2 ) )                    // Or Not Suitable For The Function
    {
        return( ERROR_INVALID_PARAMETER );                     // Return Suitable Error Code
    }
    DWORD    dwRead = 0;
    BOOL     fbStatus = ReadFile( hFile, btaBuffer, dwBufLen,  // Read The File Contents
                     &dwRead, NULL ) )                         // To The Specified Buffer
    
    dwBufLen = dwRead;                                         // Copy Bytes Read Count (If Any)
    if( !fbStatus )                                            // If Failed
    {                                                          
        return( GetLastError() );                              // Return Failure Reason
    }
    BYTE   &cX = btaBuffer[ 0 ];                               // Get First Character
    BYTE   &cY = btaBuffer[ 1 ];                               // Get Second Character

    cX ^= Y, cX ^= cY ^= cX;                                   // Swap Characters In-Place

    return( ERROR_SUCCESS );                                   // Return Success Code
}

First, the coding standard-related parts of the code:

  1. Functions should always return a status value indicating success or failure, and additional information if possible.  No void or bool functions unless the action that the function performs is atomic and has very few reasons for failure.  This function returns standard Win32 error codes.
     
  2. Avoid manipulating your own resources in utility functions if possible.  That way, you reduce the chance of that utility code being responsible for not closing a particular file, or leaking some memory under certain situations.
     
  3. Negative Buffer sizes do not make sense, so use an unsigned value for them.
     
  4. Any function that takes a previously allocated/sized buffer as a parameter must take the available/usable size of that buffer as well.
     
  5. All pointers and buffer parameters are to be at least NULL and length checked before use.  If you dereference a NULL pointer, you did not follow this simple rule.
     
  6. All line-by-line comments start at column 61 and code lines are to be broken before that column whenever possible (quoted strings are an exception to the "line break" rule).  Why write comments like that?  Using a piece of paper or your hand, cover the comments and have a non-technical (non-developer) person try to tell you what the code is doing.  Now, switch and cover the code and/or expose the comments and ask again.  You have very likely just answered your own question!
     
  7. Never hide or mask an operating system generated error unless required.  The OS has many more error messages than your application does, reuse them whenever possible.
     
  8. When taking a buffer for processing, return the length of processed data if not deterministic (the reference on dwBufLen).
     
  9. And lastly, as the implementation of the swap demonstrates, always favor the KISS Philosophy over trying to be too fancy!

Second, the coding style-related parts of the code:

  1. Variables shall use the "reverse-Hungarian" notation of naming.  In this example, "h" for "HANDLE", "bta" for "BYTE array", "fb" for "Fake Bool or BOOL" and "dw" for DWORD.
     
  2. Use array notation in parameter lists for buffers of known or specified size, and pointer notation for buffers of unknown (but deterministic) size like NUL-terminated character strings.  Also, only use pointers when a parameter can be NULL and/or optional.  The rational behind that is that a pointer CAN point to a block of memory (or NULL), but an array IS a block of memory (even though arrays degrade into pointers).
     
  3. Double-indent continued lines from the indented "point of origin".
     
  4. If statements and loops will always use brackets (compound statement), even for single-line controlled statements, and they will always exist on their own lines at the same indent level as the controlling statement/loop.  Same for functions, classes, structs, etc.

The coding standard parts are obviously more important.  Just about any developer can use the "LTTLS" (Look To The Left, Stupid) technique to find out what a variable's type is, and can figure out different indenting and bracketing behavior.

An easy way to tell the difference between parts that are style and parts that are standard is to compare the functionality of the code if either element was removed or changed.  For example, if the style points were not followed for the above code, the code would still work exactly the same way, with exactly the same behavior and safety checks.  However, if you removed the standard parts of the code, you then reduce the codes "safety" and functionality.  That is the difference between the two; standard is obviously more important than style.
 

Designing A Coding Standard

Designing a coding standard is much harder than designing a coding style.  Many things have to be taken into consideration, and you must be careful not to make it so strict as to limit the creativity of your developers.  The purpose of a coding standard is to create good habits in your development staff.

Some of the above points from JRTwine Software's Coding Standards can go a long way toward improving the quality of your code.  For example:

  1. Any function that takes a previously allocated/sized buffer as a parameter must take the available/usable size of that buffer as well.
     
  2. All pointers and buffer parameters are to be at least NULL and length checked before use.  If you dereference a NULL pointer, you did not follow this simple rule.

Some of them may seem like common sense.  But experience has shown that common sense is not common.  Design your coding standards accordingly.
 

Adhering To Coding Standards

As shown above, adhering to a well designed coding standard can give your software development an edge.  The hard part is getting developers to adhere to it.  While I am not going to tackle the various methods that can achieve this goal, I will offer one: accountability.  Accountability will generally cause developers to write better code.  If they wrote a bug, they should fix it.  If the bug would have been prevented by adhering to the standard, it should be brought to their attention.  The flip side of this is that they should be rewarded for writing good code.

 

[Previous Article In Segment] [Next Article In Segment]
 

The contents of this web site are Copyright ©1998-2006 by JRTwine Software, LLC. All Rights Reserved. 
Legal and Copyright Information.
bottrap link