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