Coding Guidelines

This document adds to, and in one case replaces, material on pages 34-35 in the Reek book, Pointers on C.

First, I disagree with Reek's point number 4. The problem with <tab> characters, in addition to indenting code too much, is that their meaning (how wide a tab stop is) is always interpreted by software. Your editor, my editor, a printer, and commands such as cat, less, and tail might all substitute different numbers of spaces for each <tab> character in your source code, making it very difficult to read. The only solution is to type spaces explicitly to indent your code, or better yet, to use a "real editor" to substitute spaces whenever you press the Tab key to indent your code. On UNIX, pico is easy to use, but is not useful for editing source code because, among other things, it does not allow you to substitute spaces for <tab> characters. On Windows, Notepad has the same problems. However, vim is a good programming editor for UNIX, and pfe, [ available here ], is a good programming editor for Windows.

Also, I find that an indent of 2 spaces is perfectly legible, whereas the problem of code getting squeezed at the right side of the page when using an indent of 8 is very constrictive, contrary to what Reek says. For this course, you can use any size indent you want, but in no case is any line of code, whether it is part of a statement or a comment, to extend past column 72.

File Header

Each source file is to start with a block of comments that tells about the contents of the file. The first line of the comment block must contain the name of the file, and nothing else. After that, put a brief summary of what the file contains. Be sure to list the name of every method defined in the file in the order in which they appear in the file. After the function name, put a brief summary of what the function does. Put your name someplace in the file header block.

For example:

      /*  printargs.c
       *
       *    This is the main module for the printargs application.
       *
       *      main    Prints command line arguments and environment
       *              variables.
       *
       *    C. Vickery
       *    Spring 1999
       */
Put #include directives after the file header comment block.

Global Variables

If the module includes definitions or references to global variables, precede them with another comment block that identifies them.

For example:

      /*  Global Variables   */

Function Headers

Every function you define, including main() must be preceded by a comment block that tells what parameters are passed to it, what value it returns, and an outline of the algorithm implemented by the function. If the function uses or modifies any global variables, they must be listed too.

Use some sort of horizontal line, such as a row of dashes or asterisks to make it easy to find the beginning of a function header. Don't put horizontal lines elsewhere in the file.

For example:

      /*  main()
       *  --------------------------------------------------
       *
       *  Parameters
       *
       *    arc   Number of command line arguments.
       *    argv  Array of command line argument strings.
       *    envp  Array of environment variable strings.
       *
       *  Return Value
       *
       *    0     Normal program exit
       *    1     Error exit
       *
       *  Calls do_print to print the command line arguments,
       *  then prints the environment variables and exits.
       *
       */

In-line Comments

If you use meaningful names for your variables, there is no need to use comments to say anything about them, but in some cases a brief statement on the same line as they are declared can be helpful. Use your own judgement on this.

If a function implements a complex algorithm, use a comment line to introduce the steps in the algorithm. These comments should parallel the algorithm outline given in the function header.

For example (assuming the function header given above):

      /* Call do_print to print the command line arguments.  */
      <code to call do_print goes here>
      
      /* Print the environment variables and exit.           */
      <Code to print the environment variables and exit goes here.>

Comment Boxes

Some people think that using asterisks to put boxes around comments is a sign of careful, professional programming. I think it's a waste of time, and makes it very difficult to edit the comments later on.

For example:

      /***************************
       *                         *
       *  Life is too short to   *
       *  spend time drawing     *
       *  boxes around comments! *
       *                         *
       ***************************/

Write Comments First

I know you're going to ignore this one, but I really mean it! Write the comments before you write the code, not afterwards.

There are two reasons for this rule:

  1. If you write the comments first, it means you have thought out what you are going to do ahead of time. Organizing the structure of your program before you start coding is a critical part of writing programs that work right and keep on working after they are released to users.
  2. It's a fact of programming life that editing a file inevitably introduces unintended changes. Nothing is more frustrating than slaving to debug some code into submission just before a deadline only to find that its broken again after you've gone through the whole thing adding comments. It's the classic student programmer's lament, "I didn't change anything and it just stopped working." Inevitably this follows a quick editing pass just to add comments but which inadvertantly changed some code too. Worst of all, when this happens you have no way of knowing where to look for the bug because you've just edited a whole lot of code and the error could be anywhere.