Path: utzoo!utgpu!water!watmath!clyde!cbosgd!ihnp4!ptsfa!ames!ucbcad!ucbvax!hplabs!hpda!athertn!ericb
From: ericb@athertn.Atherton.COM (Eric Black)
Newsgroups: comp.lang.c
Subject: Re: Making re-#includes harmless--a simple solution?
Summary: Some examples of why you might want to re-include
Message-ID: <141@teak.athertn.Atherton.COM>
Date: 11 Dec 87 17:08:04 GMT
References: <13395@think.UUCP>
Reply-To: ericb@athertn.UUCP (Eric Black)
Organization: Atherton Technology, Sunnyvale, CA
Lines: 67

In article <13395@think.UUCP> rlk@THINK.COM (Robert Krawitz) writes:
>In article <2000@bloom-beacon.MIT.EDU> newman@athena.mit.edu (Ron Newman) writes:
>]Why not change the semantics of "#include" to be:  "if, while
>]processing the current .c source file, I have already included this
>]file once, then don't include it again"?

	Because it would be a bad idea.  Robert gives a few good reasons:

>1)  The same file may have multiple names (symlinks and/or hard links).

	And NFS-style mounts that give other aliasing possibilities (we
	do that a lot here).  And, as Jerry Schwarz (and others) pointed out, 
	the various combinations of , "file", and either form with
	directory names prepended along with various -Idir cpp options
	makes it pretty hard to tell when it's the "same file".  It can
	be even harder for nested #includes (no religious wars, please!).

>2)  There may be equivalent files

	We have that case here.  When CPP or the compiler barf because
	of a redefinition caused by including two variants of a header
	file when only one should have been, the error messages given
	to the programmer are sometimes less than clear.  In such cases,
	we can have the #ifdef A_VARIANT_HAS_ALREADY_BEEN_INCLUDED clause
	provoke a real syntax error, such as:
		#ifdef SS_SUBSYSTEM_VARIANT_DEFINED

		!?!?!?!? More meaningful message, which the programmer
			 can find when he edits this "standard" foo.h
			 file to see why it got a syntax error
		#else
		#define SS_SUBSYSTEM_VARIANT_DEFINED

		/* continue with the definitions

		#endif SS_SUBSYSTEM_VARIANT_DEFINED

	Of course, we can nest the two techniques, to allow harmless
	re-inclusion of the one file while still catching the erroneous
	inclusion of a second mutually-exclusive variant.

>3)  Sometimes it may be DESIRED to include the same file multiple times.

	Yes, Virginia, you may want to have something like "recursive"
	header files, where on subsequent inclusions some symbols
	are re-defined, or un-defined.  This could certainly be done
	with separate files, but then you have two files to maintain,
	and if you are changing symbol definitions it's a lot easier
	to coordinate and keep them consistent if they are in one file
	with lots of comments, rather than two.

>Artificial constraints
>like this to try to recover from simple programming errors just make
>compilers more complicated and bug-prone, and prevent the programmer
>from deliberately doing something which may be unobvious but useful.

	We all know that one technique for helping the compiler to
	warn the programmer about a "=" where he really meant "=="
	(like in "if (a = 1)") is to get into the habit of coding
	it as "if (1 == a)"; then if you blow it the compiler can
	complain.  That doesn't mean that we want the compiler to
	silently disallow my coding it the first way!

-- 
Eric Black	"Garbage in, Gospel out"
   UUCP:	{sun!sunncal,hpda}!athertn!ericb
   Domainist:	ericb@Atherton.COM