mveao@cbnews.ATT.COM (eric.a.olson) (08/30/89)
I have a file that needs to include 30 or so other files. The original author wrote it to include "all.h" where "all.h" includes the other 30 files. I am trying to compile it in a Viewpath environment with nmake. The preprocessor seems to want to look for the second-level included files in the same directory where the "all.h" file was found. A local copy of a second-level .h file is totally ignored unless "all.h" is in the first view. Is this normal behavior?
scs@hstbme.mit.edu (Steve Summit) (09/09/89)
In article <9275@cbnews.ATT.COM> mveao@cbnews.ATT.COM (eric.a.olson) writes: > I have a file that needs to include 30 or so other files. > The original author wrote it to include "all.h" where > "all.h" includes the other 30 files. > The preprocessor seems to want to look for the second-level > included files in the same directory where the "all.h" file > was found. A local copy of a second-level .h file is totally > ignored unless "all.h" is in the first view. > Is this normal behavior? Yes. It is a not-universally-known and possibly surprising fact that #include with double quotes searches in the directory of the file doing the #including, not (necessarily) in the current directory from which the compiler was invoked. I am currently working on a large project, various versions of which are compiled in different directories, referencing source files in one master directory. So that I can "tune" the builds with special header files in the various build directories, I occasionally use angle brackets instead of double quotes: #include <tunable.h> /* <> so copy in directory other than that */ /* of source file can be selected with -I */ The CFLAGS macro in my Makefile then always contains -I. (The trick applies only to a handful of header files for which I wish multiple versions to exist; most project-related header files are kept in the master source directory, and #included with double quotes, making the default behavior for double quote searching useful and correct. In fact, that's probably why the behavior was designed that way.) The rules for #include file searching can seem capricious at first, but it's surprising how many useful effects you can achieve by using them knowingly. Note that the search behavior is quite implementation-defined. I have described the Unix behavior; other systems generally try to emulate it, with varying degrees of success. The ANSI standard says, according to K&R II (sec. A12.4), that "a control line of the form #include "filename" searches first in association with the original source file (a deliberately implementation-dependent phrase)" and then in whatever other places that #include <filename> would search. The pANS does not require that there be the notion of a directory, nor probably that there be the notion of a "source file." Steve Summit
henry@utzoo.uucp (Henry Spencer) (09/10/89)
In article <14172@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >... It is a not-universally-known and possibly surprising fact >that #include with double quotes searches in the directory of the >file doing the #including, not (necessarily) in the current >directory from which the compiler was invoked. One reason why it isn't universally known is that it's not universally true. >... The ANSI >standard says, according to K&R II (sec. A12.4), that "a control >line of the form > > #include "filename" > >searches first in association with the original source file (a >deliberately implementation-dependent phrase)" ... Beware, this is one respect in which K&R2 is outdated. The Oct 88 draft, more or less definitive, just says "searches in an implementation-defined manner". This is an area where implementations differ, partly because the two major oracles -- K&R1 and the Unix cpp -- disagree. -- V7 /bin/mail source: 554 lines.| Henry Spencer at U of Toronto Zoology 1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
tneff@bfmny0.UU.NET (Tom Neff) (09/10/89)
I have regularly been inconvenienced by various vendors' #include search logic. (Maybe "logic" is too strong a word. :-) ) Most recently I slapped together a "temp compile" script for use under a client's "vi". (No mail about EMACS please; I know, I know!) I wrote the current file to something in /tmp and ran that through "cc -S". Boom, quoted includes blew up. Fortunately the -I switch in SV3.2 cc handles "x.h" and not just <x.h> so that circumvented the problem in most cases; but editing a file in another directory was tougher. I think it was kind of stupid not to suggest some rules about what a compiler should do IF directories exist in the host environment. Even where they don't, there's often a comparable concept (floppy drives, account #s, volumes etc). Real authors distributing real software have to deal with junk like this. Guidelines would be nice. -- Annex Canada now! We need the room, \) Tom Neff and who's going to stop us. (\ tneff@bfmny0.UU.NET
henry@utzoo.uucp (Henry Spencer) (09/10/89)
In article <14647@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes: >I think it was kind of stupid not to suggest some rules about what a >compiler should do IF directories exist in the host environment... As I recall (I'm at home and my X3J11 stuff is at work), the Rationale in fact comes right out and says that X3J11 hopes everyone will use K&R1 search rules. -- V7 /bin/mail source: 554 lines.| Henry Spencer at U of Toronto Zoology 1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
penneyj@servio.UUCP (D. Jason Penney) (09/11/89)
In article <14172@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: > >Yes. It is a not-universally-known and possibly surprising fact >that #include with double quotes searches in the directory of the >file doing the #including, not (necessarily) in the current >directory from which the compiler was invoked. > We also have a large programming project written in C. One objective in the design of our programming methodology was to allow a programmer to check out any set of source files (including .h files) and then do a "local make", building a variant of the system against standard source in the "product directory". For instance, one person may wish to make substantial changes to the compiler subsystem while another person may be testing user interfaces. Clearly the first person doesn't want to test with a broken interface and the second doesn't need a broken compiler. If we have the following include layout: /**************************/ /* a.h */ typedef long OopType; /**************************/ /* b.h */ #include "a.h" OopType aGlobalVar; /**************************/ /* x.c */ #include "b.h" aGlobalVar = 10; /**************************/ and then, if the user checks out b.h into his local directory and then compiles x.c in the product directory, the WRONG version of b.h will be included in the resulting compilation! Our programming methodology takes Steve Summit's approach one step further: we NEVER use includes with double-quotes. We ALWAYS use angle-bracket includes and specify the search path appropriately in the compile step. Some veteran C programmers have been astonished by this, but I think this is yet again another example where "programming in the large" requires a different approach than programming in the small. So here is a philosophical question, to which I would appreciate REPLIES and not FOLLOWUPs: what is the use of double-quote includes? I have followed corporate programming style in my own small programs, and I have yet seen a situation where the double-quote includes were strictly necessary. -- D. Jason Penney Ph: (503) 629-8383 Beaverton, OR 97006 uucp: ...uunet!servio!penneyj STANDARD DISCLAIMER: Should I or my opinions be caught or killed, the company will disavow any knowledge of my actions...
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/13/89)
In article <249@servio.UUCP> penneyj@servio.UUCP (D. Jason Penney) writes: >So here is a philosophical question, to which I would appreciate REPLIES >and not FOLLOWUPs: what is the use of double-quote includes? Since this information is probably of general interest, I'm posting it: #include <stuff> officially obtains definitions from the implementation, while #include "stuff" officially gets them from source files (header files) provided with the program. <stuff> can actually be built into the compiler, for example, and in general may not be something you can conveniently add to. There is no C-language requirement for anything like the UNIX "cc -Iwherever" facility.