Declarations

Global declarations should begin in column 1. All external data declaration should be preceded by the extern keyword. If an external variable is an array that is defined with an explicit size, then the array bounds must be repeated in the extern declaration unless the size is always encoded in the array (e.g., a read-only character array that is always null-terminated). Repeated size declarations are particularly beneficial to someone picking up code written by another.

The ``pointer'' qualifier, `*', should be with the variable name rather than with the type.

char		*s, *t, *u;
instead of
char*	s, t, u;
which is wrong, since `t' and `u' do not get declared as pointers.

Unrelated declarations, even of the same type, should be on separate lines. A comment describing the role of the object being declared should be included, with the exception that a list of #defined constants do not need comments if the constant names are sufficient documentation. The names, values, and comments are usually tabbed so that they line up underneath each other. Use the tab character rather than blanks (spaces). For structure and union template declarations, each element should be alone on a line with a comment describing it. The opening brace ({) should be on the same line as the structure tag, and the closing brace (}) should be in column 1.

struct boat {
	int		wllength;	/* water line length in meters */
	int		type;		/* see below */
	long		sailarea;	/* sail area in square mm */
};

/* defines for boat.type */
#define	KETCH	(1)
#define	YAWL	(2)
#define	SLOOP	(3)
#define	SQRIG	(4)
#define	MOTOR	(5)

These defines are sometimes put right after the declaration of type, within the struct declaration, with enough tabs after the `#' to indent define one level more than the structure member declarations. When the actual values are unimportant, the enum facility is better.

enum bt { KETCH=1, YAWL, SLOOP, SQRIG, MOTOR };
struct boat {
	int		wllength;	/* water line length in meters */
	enum bt		type;		/* what kind of boat */
	long		sailarea;	/* sail area in square mm */
};

Any variable whose initial value is important should be explicitly initialized, or at the very least should be commented to indicate that C's default initialization to zero is being relied upon. The empty initializer, ``{}'', should never be used. Structure initializations should be fully parenthesized with braces. Constants used to initialize longs should be explicitly long. Use capital letters; for example two long ``2l'' looks a lot like ``21'', the number twenty-one.

int		x = 1;
char		*msg = "message";
struct boat	winner[] = {
	{ 40, YAWL, 6000000L },
	{ 28, MOTOR, 0L },
	{ 0 },
};

In any file which is part of a larger whole rather than a self-contained program, maximum use should be made of the static keyword to make functions and variables local to single files. Variables in particular should be accessible from other files only when there is a clear need that cannot be filled in another way. Such usage should be commented to make it clear that another file's variables are being used; the comment should name the other file. If your debugger hides static objects you need to see during debugging, declare them as STATIC and #define STATIC as needed.

The most important types should be highlighted by typedeffing them, even if they are only integers, as the unique name makes the program easier to read (as long as there are only a few things typedeffed to integers!). Avoid typedeffing structures and unions, as this hides the fact that an object is composite from the code reader.

The return type of functions should always be declared. Always use function prototypes. One common mistake is to omit the declaration of external math functions that return double. The compiler then assumes that the return value is an integer and the bits are dutifully converted into a (meaningless) floating point value.

``C takes the point of view that the programmer is always right.'' - Michael DeCorte