Recommended C Style and Coding Standards
L.W. Cannon
R.A. Elliott
L.W. Kirchhoff
J.H. Miller
J.M. Milner
R.W. Mitze
E.P. Schan
N.O. Whittington
Bell Labs
Henry Spencer
Zoology Computer Systems
University of Toronto
David Keppel
EECS, UC Berkeley
CS&E, University of Washington
Mark Brader
SoftQuad Incorporated
Toronto
ABSTRACT
This document is an updated version of the Indian Hill C Style and Coding Stan-
dards paper, with modifications by the last three authors. It describes a recommended
coding standard for C programs. The scope is coding style, not functional organization.
February 19, 1997
Recommended C Style and Coding Standards
L.W. Cannon
R.A. Elliott
L.W. Kirchhoff
J.H. Miller
J.M. Milner
R.W. Mitze
E.P. Schan
N.O. Whittington
Bell Labs
Henry Spencer
Zoology Computer Systems
University of Toronto
David Keppel
EECS, UC Berkeley
CS&E, University of Washington
Mark Brader
SoftQuad Incorporated
Toronto
1. Introduction
This document is a modified version of a document from a committee formed at AT&T’s Indian Hill
labs to establish a common set of coding standards and recommendations for the Indian Hill community.
The scope of this work is C coding style. Good style should encourage consistent layout, improve portabil-
ity, and reduce errors. This work does not cover functional organization, or general issues such as the use
of gotos. We
1
have tried to combine previous work [1,6,8] on C style into a uniform set of standards that
should be appropriate for any project using C, although parts are biased towards particular systems. Of
necessity, these standards cannot cover all situations. Experience and informed judgement count for much.
Programmers who encounter unusual situations should consult either experienced C programmers or code
written by experienced C programmers (preferably following these rules).
The standards in this document are not of themselves required, but individual institutions or groups
may adopt part or all of them as a part of program acceptance. It is therefore likely that others at your insti-
tution will code in a similar style. Ultimately, the goal of these standards is to increase portability, reduce
maintenance, and above all improve clarity.
Many of the style choices here are somewhat arbitrary. Mixed coding style is harder to maintain
than bad coding style. When changing existing code it is better to conform to the style (indentation, spac-
ing, commenting, naming conventions) of the existing code than it is to blindly follow this document.
‘‘To be clear is professional; not to be clear is unprofessional.’’ — Sir Ernest Gowers.
hhhhhhhhhhhhhhhhhh
1. The opinions in this document do not reflect the opinions of all authors. This is still an evolving document. Please send com-
ments and suggestions to pardo@cs.washington.edu or {rutgers,cornell,ucsd,ubc-cs,tektronix}!uw-beaver!june!pardo
Recommended C Coding Standards Revision: 6.0 25 June 1990
-2-
2. File Organization
A file consists of various sections that should be separated by several blank lines. Although there is
no maximum length limit for source files, files with more than about 1000 lines are cumbersome to deal
with. The editor may not have enough temp space to edit the file, compilations will go more slowly, etc.
Many rows of asterisks, for example, present little information compared to the time it takes to scroll past,
and are discouraged. Lines longer than 79 columns are not handled well by all terminals and should be
avoided if possible. Excessively long lines which result from deep indenting are often a symptom of
poorly-organized code.
2.1. File Naming Conventions
File names are made up of a base name, and an optional period and suffix. The first character of the
name should be a letter and all characters (except the period) should be lower-case letters and numbers.
The base name should be eight or fewer characters and the suffix should be three or fewer characters (four,
if you include the period). These rules apply to both program files and default files used and produced by
the program (e.g., ‘‘rogue.sav’’).
Some compilers and tools require certain suffix conventions for names of files [5]. The following
suffixes are required:
g
C source file names must end in .c
g
Assembler source file names must end in .s
The following conventions are universally followed:
g
Relocatable object file names end in .o
g
Include header file names end in .h. An alternate convention that may be preferable in multi-
language environments is to suffix both the language type and .h (e.g. ‘‘foo.c.h’’ or ‘‘foo.ch’’).
g
Yacc source file names end in .y
g
Lex source file names end in .l
C++ has compiler-dependent suffix conventions, including .c, ..c, .cc, .c.c, and .C. Since much C
code is also C++ code, there is no clear solution here.
In addition, it is conventional to use ‘‘Makefile’’ (not ‘‘makefile’’) for the control file for make (for
systems that support it) and ‘‘README’’ for a summary of the contents of the directory or directory tree.
2.2. Program Files
The suggested order of sections for a program file is as follows:
1. First in the file is a prologue that tells what is in that file. A description of the purpose of the objects
in the files (whether they be functions, external data declarations or definitions, or something else) is
more useful than a list of the object names. The prologue may optionally contain author(s), revision
control information, references, etc.
2. Any header file includes should be next. If the include is for a non-obvious reason, the reason should
be commented. In most cases, system include files like stdio.h should be included before user
include files.
3. Any defines and typedefs that apply to the file as a whole are next. One normal order is to have
‘‘constant’’ macros first, then ‘‘function’’ macros, then typedefs and enums.
4. Next come the global (external) data declarations, usually in the order: externs, non-static globals,
static globals. If a set of defines applies to a particular piece of global data (such as a flags word), the
defines should be immediately after the data declaration or embedded in structure declarations,
indented to put the defines one level deeper than the first keyword of the declaration to which they
apply.
5. The functions come last, and should be in some sort of meaningful order. Like functions should
appear together. A ‘‘breadth-first’’ approach (functions on a similar level of abstraction together) is
preferred over depth-first (functions defined as soon as possible before or after their calls).
Recommended C Coding Standards Revision: 6.0 25 June 1990
-3-
Considerable judgement is called for here. If defining large numbers of essentially-independent util-
ity functions, consider alphabetical order.
2.3. Header Files
Header files are files that are included in other files prior to compilation by the C preprocessor.
Some, such as stdio.h, are defined at the system level and must included by any program using the standard
I/O library. Header files are also used to contain data declarations and defines that are needed by more than
one program. Header files should be functionally organized, i.e., declarations for separate subsystems
should be in separate header files. Also, if a set of declarations is likely to change when code is ported
from one machine to another, those declarations should be in a separate header file.
Avoid private header filenames that are the same as library header filenames. The statement
#include "math.h" will include the standard library math header file if the intended one is not found
in the current directory. If this is what you want to happen, comment this fact. Don’t use absolute path-
names for header files. Use the <name> construction for getting them from a standard place, or define
them relative to the current directory. The ‘‘include-path’’ option of the C compiler (−I on many systems)
is the best way to handle extensive private libraries of header files; it permits reorganizing the directory
structure without having to alter source files.
Header files that declare functions or external variables should be included in the file that defines the
function or variable. That way, the compiler can do type checking and the external declaration will always
agree with the definition.
Defining variables in a header file is often a poor idea. Frequently it is a symptom of poor partition-
ing of code between files. Also, some objects like typedefs and initialized data definitions cannot be seen
twice by the compiler in one compilation. On some systems, repeating uninitialized declarations without
the extern keyword also causes problems. Repeated declarations can happen if include files are nested and
will cause the compilation to fail.
Header files should not be nested. The prologue for a header file should, therefore, describe what
other headers need to be #included for the header to be functional. In extreme cases, where a large number
of header files are to be included in several different source files, it is acceptable to put all common #in-
cludes in one include file.
It is common to put the following into each .h file to prevent accidental double-inclusion.
#ifndef EXAMPLE_H
#define EXAMPLE_H
... /* body of example.h file */
#endif /* EXAMPLE_H */
This double-inclusion mechanism should not be relied upon, particularly to perform nested includes.
2.4. Other Files
It is conventional to have a file called ‘‘README’’ to document both ‘‘the bigger picture’’ and is-
sues for the program as a whole. For example, it is common to include a list of all conditional compilation
flags and what they mean. It is also common to list files that are machine dependent, etc.
3. Comments
‘‘When the code and the comments disagree, both are probably wrong.’’ — Norm Schryer
The comments should describe what is happening, how it is being done, what parameters mean,
which globals are used and which are modified, and any restrictions or bugs. Avoid, however, comments
that are clear from the code, as such information rapidly gets out of date. Comments that disagree with the
code are of negative value. Short comments should be what comments, such as ‘‘compute mean value’’,
rather than how comments such as ‘‘sum of values divided by n’’. C is not assembler; putting a comment
at the top of a 3−10 line section telling what it does overall is often more useful than a comment on each
line describing micrologic.
Recommended C Coding Standards Revision: 6.0 25 June 1990
-4-
Comments should justify offensive code. The justification should be that something bad will happen
if unoffensive code is used. Just making code faster is not enough to rationalize a hack; the performance
must be shown to be unacceptable without the hack. The comment should explain the unacceptable
behavior and describe why the hack is a ‘‘good’’ fix.
Comments that describe data structures, algorithms, etc., should be in block comment form with the
opening /* in columns 1-2, a * in column 2 before each line of comment text, and the closing */ in
columns 2-3. An alternative is to have ** in columns 1-2, and put the closing */ also in 1-2.
/*
* Here is a block comment.
* The comment text should be tabbed or spaced over uniformly.
* The opening slash-star and closing star-slash are alone on a line.
*/
/*
** Alternate format for block comments
*/
Note that grep ’ˆ.\*’ will catch all block comments in the file
2
. Very long block comments such as
drawn-out discussions and copyright notices often start with /* in columns 1-2, no leading * before lines
of text, and the closing */ in columns 1-2. Block comments inside a function are appropriate, and they
should be tabbed over to the same tab setting as the code that they describe. One-line comments alone on a
line should be indented to the tab setting of the code that follows.
if (argc > 1) {
/* Get input file from command line. */
if (freopen(argv[1], "r", stdin) == NULL) {
perror (argv[1]);
}
}
Very short comments may appear on the same line as the code they describe, and should be tabbed
over to separate them from the statements. If more than one short comment appears in a block of code they
should all be tabbed to the same tab setting.
if (a == EXCEPTION) {
b = TRUE; /* special case */
} else {
b = isprime(a); /* works only for odd a */
}
4. 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;
hhhhhhhhhhhhhhhhhh
2. Some automated program-analysis packages use different characters before comment lines as a marker for lines with specific
items of information. In particular, a line with a ‘−’ in a comment preceding a function is sometimes assumed to be a one-line
summary of the function’s purpose.
Recommended C Coding Standards Revision: 6.0 25 June 1990