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 or windows and should be avoided if possible. Excessively long lines which result from deep indenting are often a symptom of poorly-organized code.
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:
The following conventions are universally followed:
In addition, it is conventional to use ``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.
The suggested order of sections for a program file is as follows:
/*
* bitmap -- Routines that operate on square bitmaps
*
* (C) Copyright Yoyodyne Enterprises. All rights reserved.
*
* Author: John Smith
*
* $Header$
*
*/
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 pathnames 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 partitioning 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 #includes 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.
It is conventional to have a file called ``README'' to document both ``the bigger picture'' and issues 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.