[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A module is a logically related collection of data and code grouped together for convenience. A module consists of a public header file and one or more C source files that implement the public interface and any needed private interfaces. If the module contains multiple C source files, then it may also have a private header file for use only by its own source files.
Names of non-static, private functions shared between source files in a multi-file module must also include the prefix.
Limit file names to 14 characters at most due to a limitation of old System V filesystems. Abbreviate aggressively to fit within this limit.
#include
a minimal set of needed header
files. "A minimal set" does not mean one header file that in turn
#include
s every needed or unneeded header! In fact, don't depend
on included header files to include your own dependencies, just their
own.
In particular, if a header file uses size_t
, be sure to
#include <stddef.h>
, or some other standard C library header that
also defines it if it is needed for another reason. If a header file
uses FILE
, be sure to #include <stdio.h>
.
Do not include a header file just for struct tag;
, which
creates unnecessary dependencies. Write the struct tag;
line inline.
Header file inclusion should be idempotent; that is, including a header multiple times should have the same effect as including it once. One possible exception is headers for debugging, like `debug-print.h' (discussed below).
module_module_init()
.
The corresponding uninitialization routine is
module_module_uninit()
. Check with an assertion at every
function entry point that the module has been initialized.
Alternatively, don't require explicit initialization: initialize at the first call to any function in the module. For an ADT usually the first call has to be to one particular function anyhow.
NDEBUG
to turn off assertions and similar code that only
kicks in when something goes wrong. These should be nonintrusive tests
that do not cause anything user-visible to happen when nothing untoward
is detected, although they may legitimately slow the program down
considerably and may add members to structures in public header files.
Due to the last property, normally the entire program should be compiled
with the same NDEBUG
setting (either defined or undefined).
Define DEBUG
to turn on intrusive debug code. This code may do
things such as print extra messages to stderr
or stdout
,
create log files, and so on. Whether DEBUG
is defined should not
affect definitions in public header files. This flag should be defined
or undefined on a per-module basis. It is reasonable to include a
#define
or #undef
for it at the top of a module's source
file or private header file. DEBUG
should not be defined when
NDEBUG
is defined.
Use the macros defined in `debug-print.h' for conditional output to
stderr
based on whether DEBUG
is defined. Be sure to
#include
this file after the #define
or
#undef
for DEBUG
, if any.
UNIT_TEST
, or by another file named
`module-test.c'.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |