Path: utzoo!attcan!uunet!lll-winken!xanth!mcnc!rti!xyzzy!agarn!throopw From: throopw@agarn.dg.com (Wayne A. Throop) Newsgroups: comp.lang.c Subject: Re: Recursive #includes Keywords: recursive includes, modularity Message-ID: <3701@xyzzy.UUCP> Date: 28 Feb 89 18:37:18 GMT References: <570@marob.MASA.COM> <9727@smoke.BRL.MIL> <964@philmds.UUCP> <9736@smoke.BRL.MIL> Sender: usenet@xyzzy.UUCP Lines: 55 > gwyn@smoke.BRL.MIL (Doug Gwyn ) >> leo@philmds.UUCP (Leo de Wit) >>> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) >>> It's easy to get the Makefile correct; just declare that a header >>> depends on the others that it #includes. >> This is not correct, as it is never correct to declare make dependencies >> between source files (this includes header files as well). > Sorry, but it IS technically correct. Dependence is a transitive > property. > "make" has an inherent design problem in that it doesn't properly > distinguish between logical and physical dependencies. It seems to me that to claim both that it is technically correct and that make's rules run into a problem here is to miss the point Leo has to make. Of course, I think Leo is also missing at least some of the points Doug has to make. Let me try to untangle what I see as partial truth on each side. First, dependence *is* indeed a transitive property. But the recommended use of make is not technically correct, as Doug himself points out just after claiming that it is. Make does not distinguish between "needed to construct" and "needed to use as input". Make has only the concept "needed to construct". Leo is pointing out that, given only the concept "needed to construct", it is never correct to say that a source "depends" upon another source. But on the other hand, it is correct to say that since dependence is transitive, the .o does not need to depend directly upon all include files that the compiler will read. It seems to me that the "correct" way (or at least a better way) of dealing with trees of include files is to introduce a phantom object which depends upon "this .h and the phantom objects of the .hs it includes". The .o would depend on "this .c and the phantom objects of the .hs it includes". By "phantom object", I mean something not corresponding to a file in the file system. In this scheme, as in make, there is only "needed to construct", and therefore no source should depend upon another source directly. But the "construction" of the conceptual object of "include file foo is ready to be read" CAN depend upon a source, namely include file foo. The alternative that Doug suggests, of having more than one kind of "needed for" seems overly complicated. The scheme I suggest works even when the relevant .h files are constructed on the fly themselves, (assuming some modifications to make, of course). ( This scheme still doesn't deal with cyclic includes broken with #ifdef... but despite there being ways to deal with that as well, my personal feeling is "don't DO that" is a good remedy. ) -- The nation that controls magnetism will control... The Universe! --- Dick Tracy Wayne Throop !mcnc!rti!xyzzy!throopw