Path: utzoo!attcan!uunet!ncrlnk!ncrcae!hubcap!gatech!mcnc!thorin!alanine!tuck From: tuck@alanine.cs.unc.edu (Russ Tuck) Newsgroups: comp.lang.c++ Subject: Re: Including header files minimally. Message-ID: <5455@thorin.cs.unc.edu> Date: 21 Nov 88 15:37:05 GMT References: <3561@pt.cs.cmu.edu> <7860@nsc.nsc.com> <3614@pt.cs.cmu.edu> Sender: news@thorin.cs.unc.edu Reply-To: tuck@alanine.UUCP (Russ Tuck) Organization: University Of North Carolina, Chapel Hill Lines: 60 In article <3614@pt.cs.cmu.edu> dld@f.gp.cs.cmu.edu (David Detlefs) writes: >...My solution ... To explain it >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. This isn't true. An included file may generate different code if any preprocessor definitions have changed or been added. As a trivial example, consider a triv.h file containing only "int fn();", and the following fragment: #include "triv.h" #define int unsigned long #include "triv.h" Without a good reason and documentation, this is certainly highly questionable code, but it shows that *any* identifier or keyword can be redefined. You can't be sure that an include file will generate the same code twice unless the preprocessor definitions have not changed at all (and even this is probably not sufficient to make a guarantee). Let me give a motivating example for code like this. I am implementing a hierarchy of mathematical types, derived from a single base, and need to provide math and logic expressions for all these classes. Unfortunately, just providing all the operator methods for the base class is not sufficient. The base class methods return base class values, which can not be assigned to derived class objects (because the additional info contained in the derived class was lost when the operator method converted the result to the base class). So, I have to redefine all the operator methods for each derived class. To avoid many potential typographic and minor logic errors, I do this with a single include file with declarations something like: type operator+(type) Then the library user includes a single library definition .h file, which includes the above file multiple times, something like this: #define type base #include "my_math_defs.h" #define type derived #include "my_math_defs.h" (This is greatly simplified from the real code, but gives a feel for one case where a .h file can usefully generate different code without #if's.) >...While we process the #include file for the first time, we record all >the externally defined symbols uses in #if's, and their values when >they were first used. If we encounter an #include of this file again, >we include it only if one or more of those symbols has a different >value. > >This solution requires no special flags, and always gets it right. No. It's not this simple. For complete safety, it must be included again if anything about the set of preprocessor definitions has changed (or perhaps even if the #include just comes in a different code context). Russ Tuck internet: tuck@cs.unc.edu Computer Science Dept., Sitterson Hall csnet: tuck@unc University of North Carolina uucp: {ihnp4|decvax}!mcnc!unc!tuck Chapel Hill, NC 27599-3175, USA Phone: (919) 962-1755 or 962-1932