C Style
Doug Gwyn
gwyn at smoke.BRL.MIL
Wed Jan 11 18:48:50 AEST 1989
In article <2688 at ficc.uu.net> peter at ficc.uu.net (Peter da Silva) writes:
>I have been told that the following mechanism for handling nested includes
>is unreliable and/or unportable, but for the life of me I can't see how:
>graphics.h:
> #ifndef GRAPHICS_H
> #define GRAPHICS_H
> ...
> #endif
>windows.h:
> ...
> #ifndef GRAPHICS_H
> #include GRAPHICS_H
> #endif
> ...
>menus.h:
> ...
> #ifndef GRAPHICS_H
> #include GRAPHICS_H
> #endif
> ...
>Now this allows a programmer to include windows.h and menus.h, without
>having to (a) know they need to include graphics.h, and (b) worry about
>graphics.h being included twice.
>What's wrong with this picture?
The only thing wrong is your syntax. You mean
#include "graphics.h"
in the latter two files.
In fact there is no need to place conditionals around those inclusions,
since the included file will have no effect if it is already in force,
bacause it checks its one-time lockout flag and avoids redefining things
after the first time it's included in a translation unit.
Notes:
1. GRAPHICS_H needs to be reserved for this use. If this
header is part of an application (as indicated), then you
just have to keep track of such symbols, perhaps by making
the rule that the _H suffix is reserved for them. If you
were implementing standard headers for a C implementation,
you would need to use a lockout symbol that's in the
implementation's reserved name space, e.g. __CTYPE_H.
2. If the header just defines macros and structures,
and declares types of external objects and functions,
then you don't need to ensure one-time actions, because
such actions can be repeated safely. Typedefs are the main
things that need to be protected against a second invocation.
3. Notwithstanding point 2, if the header includes others
then it should probably use lock-out symbols, to avoid
infinite recursion if the other headers include THIS one.
4. Application headers should NOT include standard headers,
because many C implementations do not provide idempotent
standard headers, so bookkeeping becomes a real mess unless
you adopt the simple rule that all application headers are
idempotent and never include system headers inside themselves.
(ANSI C requires the standard headers to be idempotent, i.e.
includable multiple times with the same effect as a single
inclusion.)
5. Include headers before doing anything else in the source.
6. We use this scheme in a major project and it works
fine.
More information about the Comp.lang.c
mailing list