Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!amdahl!nsc!rfg From: rfg@nsc.nsc.com (Ron Guilmette) Newsgroups: comp.lang.c++ Subject: Re: Including header files minimally. Message-ID: <8015@nsc.nsc.com> Date: 23 Nov 88 19:13:40 GMT References: <3561@pt.cs.cmu.edu> <7860@nsc.nsc.com> <3614@pt.cs.cmu.edu> Reply-To: rfg@nsc.nsc.com.UUCP (Ron Guilmette) Organization: National Semiconductor, Sunnyvale Lines: 113 In article <3614@pt.cs.cmu.edu> dld@f.gp.cs.cmu.edu (David Detlefs) writes: >To Ron Guilmette -- I couldn't seem to send you mail -- Several people have told me this. I don't know hat's happening but I intend to find out! >I think your idea is a very good quick-and-dirty solution -- easy to >understand, easy to implement. If someone were to take the sources to >some public domain cpp and implement it tomorrow (which is about all it >would take!), it would get a lot of use. I agree that what I proposed is "quick" I disagree that it is "dirty". I'll see if I can find the time to make the necessary mods to GNU cpp soon. If I do get it done, I will post the necessary patches here and in the GNU C and GNU C++ newsgroups. The diffs ought to be reasonably small. >People *shouldn't* write >include files that are intended to be included multiple times with >different results on each inclusion; that is an obscure practice at >best. Yet people do do this; at least they have, in include files that >we may have to keep including forever in the name of backward >compatibility. I generally agree that this seems to be a questionable practice, but I'd rather be a bit less judgemental about it. If people have found what they think are good reasons for doing this, then, to quote the Beatles, "Let it be". >Your solution, with the links, works. However, I would >hope that you would agree that it is a least somewhat unsatisfying. No I don't agree. It tastes great! No. It's less filling! Tastes great! Less filling! ... Well, OK. It is a little kludgy, but then all of cpp is just a big kludge which people keep on using year after year because it does some things very well which cannot yet be done in any other ways. >I think your solution and mine fall on a continuum... That sounds painful. I would rather fall on my sword that on a continuum! >... yours is very easy >to implement, but requires the user to perform two actions he or she >wouldn't normally have to do: use the new flag to cpp (or use the flag >to turn it off when necessary, if not including multiply is made the >default), and making extra links to certain files. Note that you run >the risk of always using the "don't include again mode," and forgetting >to turn it off... OK. The problems you point out are very valid. Looks like it is time for me to switch to plan B. In retrospect, I admit that the notion of an extra flag to cpp (i.e. the don't do multiple includes flag) was a dumb idea. As you have noted, it lacks true backward compatibility in the purest sense (i.e. not even having to edit your Makefiles). The multiple links to get multiple inclusions of the same single file was also a dumb idea. Plan B: So let's fix cpp to do the following. First, under "normal" circumstances, the new cpp will do just what it has traditionally done, i.e. include EACH and EVERY file called for in EACH and EVERY #include directive. Now for the trick. Pick one of the UNIX protection mode bits which is typically NEVER USED and totally INSIGNIFICANT (as least for normal source code files). Just for the sake of argument, lets pick the "set-gid" bit (i.e. 02000). Now let's say that we modify cpp so that it will *NOT* re-include any header file which has its set-gid bit set. Ta da! Presto! No more tricky links, full backwards compatibility, and best of all, the ability to control re-inclusions on a file-by-file basis in a very easy and simple manner which does *not* require any changes to Makefiles or any other files. The above scheme is simple to implement, simple to use, and simple to understand. The semantics are crystal clear and it can be slowly worked into existing code (both C and C++) on an as-needed basis. Although it would seem that this scheme is heavily dependent on UNIX-specific file modes, I believe that most operating systems have at least some ways of tagging individual files with one more meaningful bit of information. Specifically, MS-DOS also has a per-file mode, and I believe that VMS does also. >My solution requires somewhat more work... >...I don't think it is "semantically muddy."... Is my suggested approach "muddy"? I don't see how? >again: you include a file. If this file contains no #if-like >constructs, it will generate the same ***code*** every time it is included, >so it will never need to be included again. It is *NOT* true that, if there are no #if's in a given header file, then you will get the same "code" (let alone the same "effect") from each inclusion of that file. Note the following: /* something.h */ int my_array[FOOBAR]; There are no #if's in this file, but the code can still be different on different inclusions if the value of FOOBAR changes. More significant is that the "effect" of a header file (without any #if's) can be different for different inclusions, i.e.: #define NEW_FOOBAR FOO##BAR >[My] solution requires no special [cpp] flags, and always gets it right. >Your solution has the drawbacks I mentioned, but has the virtue of >being simpler to implement, and may be somewhat faster. As described above, I have figured out how to easily avoid extra cpp flags. As you note, my approach is simple and fast. I rest my case.