UCM Unitec Home Page
      

Chapter 11 - Unitec Coding Standards

 

11.1. Overview
11.2. Symbol Naming
11.3. Comments
11.4. Indentation

11.1. Overview

This chapter describes the Unitec standards for all code written for internal, as well as external distribution. The purpose of these standards is to improve the readability, organization and maintenance of source code and header files.

Standards do not develop in one day. Ideas evolve and many years of experience (and some failures) lead to the inspirations of how things can be done best. As in every society, each group working on the same project has to follow some rules. These rules are not intended to impose one person's style to the universe nor to confine creativity. Their sole purpose is to set a common base for understanding and communication. Creativity is not achieved through personal indentation styles, but by finding the best solutions and most efficient algorithms for the problems to solve. Good programming cannot be taught by preaching generalities, the way to improve programming style is by the application of few principles of good practice and a little common sense. Shortcomings show only that we are all human, and that under the pressure of a large, intellectually demanding task like writing a program, it is much too easy to do some things imperfectly. In the following sections you will find our bashful attempt to achieve perfect programming.

11.2. Symbol Naming

Many major companies (including Microsoft - they can't be wrong) use a naming convention called the 'Hungarian Prefix Notation' (e.g. szName is a zero terminated string containing a name). This standard is especially aimed at reducing type conflicts. Since modern compilers do a good job in detecting such conflicts the method has lost its strongest argument. The major drawback is the promotion of two or three character abbreviations for meaningful things. The terminology is most often known only to the small group of developers involved in the project. The possible problems for the maintenance teams are obvious. For these reasons, Unitec has chosen a more descriptive method.

Functions

Functions should be self explanatory and should be in name-case format (i.e., first letter per word upper-case lettering, all remaining characters in lower-case lettering) with no underscores used to separate words. In addition, the function name should describe the operation that is performed by the function.

Some example function names are shown below:

int LogOpen(char *fileName);
extern void ProgTerm(int rc);
extern int AddFunction(void (*func)());

Since the C language does not provide a method of hiding global symbols that are of importance in a restricted set of functions only (i.e. functions used by different modules of a library, but hidden from the application program using the library), the following convention is used:

- Global symbols of tools and libraries have an underscore added to their name, as in LogCntl_.

- Application programs avoid the use of the underscore in symbol names.

Variables

Variable names should be self-explanatory and should be in lower-case lettering for the first word, then name-case for each word thereafter:

int pageCount;
char *cmdLine;
static int firstTime = 1;

For restricted global symbols, the same conventions are used as described under the Functions section.

Constants, pseudo functions, types, tags

Constants (defines), pseudo functions (preprocessor macros), types (typedef) and tags (structure and union tag-names) should be self-explanatory and should be in upper-case lettering, with an underscore separating the words. To avoid side-effects, arguments to pseudo functions should not include assignment, increment and decrement expressions.

Some example constant names are shown below:

#define MAX_BUF    1024
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
typedef char BOOL;
struct ADDRESS
{
    char street[30];
    char town[30];
};

11.3. Comments

Judicious use of comments and consistent indentation can ease the task of reading and understanding a program. Comments can however be misused in ways that seriously affect the readability of program code. The compilers do not understand the contents of comments, so there is no way of ensuring that a comment is meaningful, describes the program accurately and is up to date. Many programs contain comments that are incomprehensible, ambiguous or just plain wrong. Bad comments can be worse than no comments. If something can be stated in the language itself, it should be, and not just mentioned in a comment. This statement is aimed at comments such as

"count" must be initialized
"flag" may not be used outside of function "Init()"
call function "Init()" first
function "Func()" takes two arguments

The most accurate information of what has to be done, is the statement itself. Once something has been stated clearly in the language, it should not be mentioned a second time in a comment:

sum = a + b;   /* sum becomes a + b */
count++;       /* increment the counter */

Such comments are worse than simply redundant, they increase the amount of text the reader has to look at and often obscure the structure of the program. A well chosen and well-written set of comments is an essential part of a good program.

Source files

Each source file (.c or .h) should contain a comment-header that contains the library or program name, the name of the file and copyright information. The copyright year should include the original year when the product was created and all subsequent years when major revisions were made.

/* Help.c:    CLib / Print help message and exit
**
** Syntax:    void Help(helpText);
**            char *helpText[];
**
** Author:    Unitec Informatik
**            Thomas Madörin
**            Leerüti 797
**            CH-8625 Gossau, Switzerland
**
** Copyright (c) 1998 by Unitec Informatik
*/

Functions

Each routine may be preceded by a short description giving the routine's purpose and any related algorithms. If the routine name intuitively describes the routine, no comment is needed.

Variables

Function arguments and local variables should only have descriptive comments if their names are not descriptive. These comments should be lined up on a right region.

Blocks

Block comments are used to describe a group of related code. Most block comments should be one line, if possible, and reside immediately above the block being commented. If more than a one line comment is needed, the extra lines should each begin with the double asterisk '**'. Block comments should be indented to match the indentation level of the line of code following it. A single blank line should precede the comment and the block of code should follow immediately after. Small blocks of code that do a specific job should be commented but not individual lines (unless the line is complex or not intuitive).

11.4. Indentation

There are several different consistent styles of indentation used. No fundamental reasons exist, to prefer one over another. Unitec has chosen the so called 'Allman' style because we think it best emphasizes the structure of the underlying code. The indention unit used is 4 characters.

Unions and structures

Unions and structures should have all members listed on individual lines and should be indented on unit from the left margin.

typedef union
{
    int logLevel;
    long fileSize;
    LOG_HDR *logHdr;
}   LOG_CNTL;

Functions

The main body of routines should have braces below the function declaration. All function code should be indented one unit.

void Help(helpText)

char *helpText[];
{
    ...
}

Function calls

Parameters in a function call should be listed with each argument followed by a comma and one space. If a routine call cannot fit on one line on the screen, it should be broken with the next half of the call and indented one ore more unites farther over. It should be split after a comma or logic symbol if possible.

Case statements

The reserved word case should be indented one unit from the switch statement, and all code information should be indented an additional unit. The colon should immediately follow each case and the statement(s) should start on a new line. The break should also be on a separate line. If the switch statement appears in a deep indentation level the word case and the statements may be indented by half a unit each. Additional levels of logic should be indented one unit.

switch (opt)
{
    case 'a':
        aOpt = TRUE;
        break;

    case 'b':
        bOpt = TRUE;
        break:

    default:
        Error("illegal option %c", opt);
}

If, for and while statements

Statements following an if, for or while should be indented one unit, and simple conditionals should use the inline ? operator.

if (aOpt == TRUE)
{
    printf("a-option set\n");
    return 1;
}

The braces enclosing the block should be aligned with the if, for or while keywords. If no statements exist for the for or while loop, the semicolon should be placed on the next line.

while (*dest++ = *src++)
    ;

 

Back to top