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