CSC 357 Coding Conventions

CSC 357 Coding Conventions



The standards for code submitted in 357 are presented in five categories:

Program Organization and Style

Except for assignment 1, all submitted programs must be organized into pairs of .c and .h files.

To guard .h files against multiple inclusion, use the standard conditional-compilation convention with "ifndef ...". E.g., for a file named X.h:

#ifndef X_included
#define X_included

    ...

#endif

Additional conventions for organization and style are the following:

  1. Use meaningfully-mnemonic names for typedefs, functions, variables, and constants.

  2. Limit function definitions to 50 lines of code or fewer, not including comments, blank lines, or lines with a single opening or closing curly brace.

  3. Avoid "magic numbers". For constants, use either preprocessor defined constants or const variables, e.g.,
    #define TAB_WIDTH 8
    
        ...
    
    for ( i = 0 ; i < TAB_WIDTH; i++)
    
        ...
    
    
    or
    const int tabsize = 8;
    
        ...
    
    for ( i = 0 ; i < tabsize; i++)
    
        ...
    
    
  4. Indent properly. The exact depth of indentation is not important, but it must be consistent. Remember, however, that if you choose to indent a full tab-stop (8 spaces) for each level, you'll get very deep very fast.

  5. There are several accepted conventions for brace placement. Choose one and follow it. In all cases, an open brace ("{") is always the last non-comment or whitespace item on a line, and a close brace ("}") is always the first.

    Three widely-used conventions are the following:

    1. Old-style (K&R) This format is dense and very readable, but sometimes open braces at the end of a line do get lost visually:
      if ( cond ) {
          /* body */;
      }
      
    2. Newer-style This is not quite as dense, but some people find it is easier to see open braces:
      if ( cond )
      {
          /* body */;
      }
      
    3. GNU-style Braces are placed halfway between outer indentation level and the inner level. A lot of old-school types think it's funny-looking, but it is the style used for code from the Free Software Foundation:
      if ( cond )
        {
          /* body */;
        }
      
  6. It is a corollary of the above, but avoid constructs that obfuscate control flow. Some programmers are fond of writing brief conditional statements on one line like this:
    if ( cond ) { thing; };
    
    or, worse yet, this:
    if ( cond ) thing;
    
    Do not do this. Not only does it violate the "an open brace is the last thing on a line" rule (above), but this sort of bracing visually obscures the control flow of the program making it difficult to read.

  7. Break long lines. Your program should have no lines over 80 characters (the standard terminal width). This is when tabs are expanded to 8-column tabstops.

    To check if your source conforms to this convention, run the following program on falcon/hornet:

    ~gfisher/bin/longlines.pl
    
    E.g.,
    hornet% ~gfisher/bin/longlines.pl foo.c
    LINES TOO LONG:
    foo.c has 1 lines over 80 characters.
    The longest was 106 characters at line 8.
    
  8. Be wary of tabs: Regardless of what you set tab stops to be in your editor, standard tab stops in the UNIX environment are every eight columns. Be sure that your indentation and line lengths are ok with standard tab stops.
    To check your code with standard tab sizes, simply cat or more it and see if it looks ok.

    Tab characters are so troublesome that many industrial coding styles forbid their use. You, too, may want to do away with tabs in your code. If your editor does not support this, look into the UNIX command expand(1).

  9. Use modular design for your programs. Functional units of your program should be implemented as independent functions. If you find yourself duplicating a lot of code, you should put it in a function and reuse it with function calls.

  10. Make data-flow explicit. That is, functions should communicate via their parameters and return values, not through global variables.


Functionality

Assignment writeups will have "black box" specifications for functionality. These specs must always be met.

In general, your programs should handle error conditions gracefully. That is, you must validate your inputs and check the return values from library and system calls for success. In case of failure, you must print an error message indicating the reason and exit with a non-zero status.

Compilation

For the greatest level of portability and reliability, it is important to stick to the most standard features of the C language. To that end, all programs submitted must compile cleanly with the gcc options "-Wall" (all warnings) and "-ansi" (follow ANSI standards).

Passing -Wall not only helps with portability, but also with correctness. For even greater assistance from the compiler, you can turn on the optimizer, with -O. The optimizer performs dataflow analysis and can detect some ininitialized variables. Note that the use of -O precludes the use of the -g debugging flag, so you'll not use -O to run your program under gdb.

In general, you should choose more common language features over more exotic ones. The -ansi option helps in this regard. For example, on-the-fly declaration of variables (in the manner of C++ or Java) is supported by the ISO C99 standard. However, many deployed compilers only conform to the ANSI C89 standard, which requires variables to be declared at the start of a block. While it is sometimes convenient to declare a variable on the run, it is much more likely to be portable to make all your declarations at the top of a block.

Documentation

  1. Each .h file must have a top-level comment that describes the functionality of the program module defined in a .h/.c file pair. The comment must include the following information:
    1. A description of the purpose of the module. The length of the description is commensurate with the size and complexity of the module. I.e., larger and more complex modules require lengthier descriptions.
    2. A summary of the functions provided.
    3. A summary of the types defined.

  2. Each typedef declaration in a .h file must be preceded with a comment describing the data representation of the type and what it is used for.

  3. Each function declaration in a .h file must be preceded with a comment that describes the external function behavior. This is a description of what the function does, not how it is implemented. Describe the use of each parameter by name, and describe the function output. Also describe any modifications made to call-by-reference parameters. Stylistically, use complete sentences, avoid passive voice.

  4. The function comment need not be repeated above the definition in the .C file, but you may do so if you like.

  5. Within the body of a function definition, each local variable must have at least a brief comment describing its use.

  6. Any non-trivial code within the body of the function should be commented. There are no specific conventions for how much of this commentary you must provide. However, if a submitted program is not fully functional and you would like it considered for partial credit, you must comment the code.

  7. Use C-Style (/* ... */) comments. While many C compilers support the C++ (and Java) style comments (// ...), they are not part of the C language and are not portable.

  8. Starting with programming assignment 3, all header, typedef, and function declarations must be doxygen compliant. This convention will be expanded upon in a future addendum to this document.


Scoring

Scoring of 357 programs will be based on execution results and adherence to coding conventions. Points for program execution are defined in the test plan for each program, on a 100-point scale.

After the execution score is determined for a program, points are deducted for any violations of the conventions specified in this handout. The following are the specific deductions:



The total maximum deduction for convention violations is 35 points out of 100. If deductions from the specific categories above add up to more than 35 points, the total deduction will be limited to 35 points overall.



index | lectures | labs | programs | handouts | solutions | examples | documentation | bin