[comp.lang.c] #include search paths

jlh@loral.UUCP (Physically Pffft) (11/10/88)

When I have a line like '#include <fred.h>' I was under the impression
that /usr/include was searched for fred.h first due to the use of <> instead
of quotes.  Is this true?  And where did I get this idea??  Now that I need
to verify it I can't find squat that tells me the difference between <> and
quotes.


								Jim


-- 
Jim Harkins		jlh@loral.cts.com
Loral Instrumentation, San Diego

rob@pbhyf.PacBell.COM (Rob Bernardo) (11/11/88)

In article <1866@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes:
+When I have a line like '#include <fred.h>' I was under the impression
+that /usr/include was searched for fred.h first due to the use of <> instead
+of quotes.  Is this true?  And where did I get this idea??  Now that I need
+to verify it I can't find squat that tells me the difference between <> and
+quotes.

See the man page for cpp(1).
-- 
Rob Bernardo, Pacific Bell UNIX/C Reusable Code Library
Email:     ...![backbone]!pacbell!pbhyf!rob   OR  rob@pbhyf.PacBell.COM
Office:    (415) 823-2417  Room 4E750A, San Ramon Valley Administrative Center
Residence: (415) 827-4301  R Bar JB, Concord, California

ok@quintus.uucp (Richard A. O'Keefe) (11/11/88)

In article <1866@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes:
>When I have a line like '#include <fred.h>' I was under the impression
>that /usr/include was searched for fred.h first due to the use of <> instead

>of quotes.

Checking CPP(SD_CMD) in the System V Interface Definition, on p330 of
Vol 2 we find the description of the -I flag (paraphrased):

	A file whose name starts with / is taken as it stands,
	whether #include </dir/file.h> or #include "/dir/file.h".
	Otherwise:

	#include "file" will look
	- first in the directory of the file containing the #include line,
	- for each "-I<directory>" in the command, in that directory,
	  in the order in which the -I arguments appeared in the command, 
	- finally in directories on a standard list (/usr/include).

	#include <file> will not look in the directory of the file
	containing the #include line, but is otherwise just like "file".

"man 1 cpp" on a SunOS 3.2 system agrees.
So /usr/include is searched LAST in both cases.  The difference between
#include "stdio.h"	and
#include <stdio.h>
is, according to these manuals, just that the former will first look for
a ./stdio.h, and the latter won't.

crossgl@ingr.UUCP (Gordon Cross) (11/11/88)

In article <1866@loral.UUCP>, jlh@loral.UUCP (Physically Pffft) writes:
> When I have a line like '#include <fred.h>' I was under the impression
> that /usr/include was searched for fred.h first due to the use of <> instead
> of quotes.  Is this true?  And where did I get this idea??  Now that I need
> to verify it I can't find squat that tells me the difference between <> and
> quotes.

There seems to be some confusion between various documents I checked
regarding this.

  1) the proposed ANSI standard says that the "filename" form "is searched for
     in association with the original source file".  What exactly does this
     mean?  I will come back to this later.  The document goes on to say that
     if the aformentioned capability "is not supported, or if the search fails,
     the line is reprocessed as if it read [ <filename> form ]." Regarding the
     <filename> form the standard only states that the preprocessor "searches
     a sequence of implementation-defined places".  Well, nothing very
     concrete here but it seems to agree with your assumption regarding
     <fred.h>!  Seems like the definition of a non-standard to me! :-) :-)

  2) A very good book on the C language, "C:  a Reference Manual" by Samuel
     P. Harbison and Guy L. Steele Jr. does say a bit more.  Regarding the
     "filename" form, Harbison & Steele state that the precessor "typically
     searches for the file first in the same directory in which the file
     containing the #include command was found, and then perhaps in other
     places according to implementation dependent search rules."  Well,
     perhaps this is what the standard was referring to with the statement
     "in association with the original source file".  On the <filename> form,
     Harbison & Steele say that it "typically does *not* search for the file
     in the same directory in which the file containing the #include command
     was found, but only in certain standard places according to implemen-
     tation dependent search rules."  This word "typically" would seem to 
     allow <fred.h> to be searched for like "fred.h" should the compiler
     writer wish it.  Hummm, so far we seem to be up the proverbal creek
     without the required paddle!! :-)

  3) Let's see, getting more implementation-specific I checked the UNIX
     System V Programmer's Reference Manual which says that the "filename"
     form "will be searched for first in the directory of the file with the
     #include line, then in directories named in -I options, and last in
     directories on a standard list."  Neither of the other two documents
     mentioned the -I options!!  And I thought of these as being a de-facto
     standard...  Regarding the <filename> form it says "the directory of
     the file with the #include line is not searched."  Okay I guess this
     means that it *does* search first in directories listed on -I options
     and lastly in the "standard" place(s).  Does -I change where your
     compiler looks first for <fred.h>??

  4) Alright time to punt; I checked Kernighan & Ritchie.  Regarding the
     "filename" form I quote:  "The named file is searched for first in the
     directory of the original source file, and then in a sequence of
     standard places."  On the <filename> form, K&R state that it "searches
     only the standard places, and not the directory of the source file."
     OK, K&R agree with your intrepretation of <fred.h>.

Overall conclusion:  experiment.  You are in the same boat I've been many
times -- when in doubt and documentation is lacking or conflicting, play with
it!!  You can usually find your (implementation-specific) answers in this
fashion.  Good luck!!


Gordon Cross
Intergraph Corp.  Huntsville, AL

guy@auspex.UUCP (Guy Harris) (11/12/88)

>When I have a line like '#include <fred.h>' I was under the impression
>that /usr/include was searched for fred.h first due to the use of <> instead
>of quotes.  Is this true?

Yes.

>And where did I get this idea??

Probably from any of a number of documents about C implementations on
UNIX.

>Now that I need to verify it I can't find squat that tells me the
>difference between <> and quotes.

From the SunOS 4.0 man page CPP(1) - other UNIX implementations may have
similar stuff in their documentation (this came from some version of the
S5 CPP(1) man page):

     #include "filename"
     #include <filename>
          Read in the contents  of  filename  at  this  location.
          This data is processed by cpp as if it were part of the
          current file.  When the <filename>  notation  is  used,
          filename  is  only searched for in the standard include
          directories.  See the -I and -Y options above for  more
          detail.   No  additional  tokens  are  permitted on the
          directive line after the final " or >.

  Details
  Directory Search Order
     #include files is:

     1.  The directory of the file  that  contains  the  #include
         request (that is, #include is relative to the file being
         scanned when the request is made).

     2.  The directories specified by  -I  options,  in  left-to-
         right order.

     3.  The standard directory(s)  (/usr/include  on  UNIX  sys-
         tems).

(the above description applies to most, if not all, UNIX systems, except
for the "-Y" option which may not be present on all UNIX systems).

And from K&R second edition:

   A 12.4 File Inclusion

	A control line fo the form

		# include <filename>

   causes the replacement of that line by the entire contents of
   the file "filename". ...  The named file is searched for in a
   sequence of implementation-dependent places.

	Similarly, a control line of the form

		# include "filename"

   searches first in association with the original source file (a
   deliberately implementation-depenent phrase), then as if in the first
   form. ...

henry@utzoo.uucp (Henry Spencer) (11/13/88)

In article <2899@ingr.UUCP> crossgl@ingr.UUCP (Gordon Cross) writes:
>  1) the proposed ANSI standard says that the "filename" form "is searched for
>     in association with the original source file".  What exactly does this
>     mean?  ...

You are reading an obsolete draft.  The May draft (which is still the latest)
just says "searched for in an implementation-defined manner".  This arises
from a combination of historical differences in compilers and the problems
of describing a file system in a system-independent way.

>     ... Regarding the
>     <filename> form the standard only states that the preprocessor "searches
>     a sequence of implementation-defined places".  Well, nothing very
>     concrete here...

Again, it's difficult to be concrete in an implementation-independent way.
Note that the <foo.h> form is specifically *not* required to refer to a
*file* at all -- the headers might even be built into the compiler.

>     ... Regarding the
>     "filename" form, Harbison & Steele state that the precessor "typically
>     searches for the file first in the same directory in which the file
>     containing the #include command was found, and then perhaps in other
>     places according to implementation dependent search rules."  Well,
>     perhaps this is what the standard was referring to with the statement
>     "in association with the original source file"...

That and other variations.  Note that "in association with the original
source file", which is more or less K&R1 wording, is *NOT* the same as
"same directory in which the file containing the #include was found" --
if you nest #includes, "original source file" and "file containing
the #include" are not the same file!  Different compilers handle this
in different ways, which is one reason for X3J11 vagueness.

>     ...  Neither of the other two documents [X3J11, H&S]
>     mentioned the -I options!!  And I thought of these as being a de-facto
>     standard...

Only on Unix and Unix-like systems.  Those documents are trying to describe
*C*, not the form of options for a particular C compiler.
-- 
Sendmail is a bug,             |     Henry Spencer at U of Toronto Zoology
not a feature.                 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

ok@quintus.uucp (Richard A. O'Keefe) (11/13/88)

In article <2899@ingr.UUCP> crossgl@ingr.UUCP (Gordon Cross) writes:
>In article <1866@loral.UUCP>, jlh@loral.UUCP (Physically Pffft) writes:
>> When I have a line like '#include <fred.h>' I was under the impression
>> that /usr/include was searched for fred.h first due to the use of <> instead

Quick reminder:  no, /usr/include/ is searched _last_ whichever form
you use.

>There seems to be some confusion between various documents I checked
>regarding this.
>     On the <filename> form,
>     Harbison & Steele say that it "typically does *not* search for the file
>     in the same directory in which the file containing the #include command
>     was found, but only in certain standard places according to implemen-
>     tation dependent search rules."  This word "typically" would seem to 
>     allow <fred.h> to be searched for like "fred.h" should the compiler
>     writer wish it.  Hummm, so far we seem to be up the proverbal creek
>     without the required paddle!! :-)

I doubt that such was their intention.  The point is that every compiler
which supports the -I flag permits this kind of thing:

	cc jim.c -I.
where jim.c contains the line
	#include <fred.h>

According to all the UNIX manuals _and_ Harbison & Steele, this will look
for fred.h in the current directory first, and that's the directory
containing the source file.  In fact we can state this as a general rule
for UNIX C compilers:  if there is at least one -I option in the command
line and the first -I option is -I., the difference between ".." and <..>
disappears.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/14/88)

In article <2899@ingr.UUCP> crossgl@ingr.UUCP (Gordon Cross) writes:
>There seems to be some confusion between various documents I checked
>regarding this.

The details vary with the implementation; the intent does not.

Use #include "file.h" when including a header source file that is
part of the application source code.

Use #include <file.h> when including a header (n.b. not necessarily
a file) provided by the C implementation, for example standard
headers or headers for vendor-provided extensions.

Do anything else and you're asking for portability problems.

scs@athena.mit.edu (Steve Summit) (11/16/88)

In article <1988Nov13.011054.23413@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
[A completely correct discussion of the #include path problem noting that]
>Different compilers handle this
>in different ways, which is one reason for X3J11 vagueness.
[and concluding that the "usual rules" are true]
>Only on Unix and Unix-like systems.  [H&S, ANSI] are trying to describe
>*C*, not the form of options for a particular C compiler.

I would like to point out that the "usual rules" have proved to
be convenient and powerful, so implementors should be encouraged
to emulate them if possible.  To reiterate, the double quoted
form searches in

	1. the directory of the source file doing the #include
	2. places listed on command line (-I)
	3. "standard" places (/usr/include)

while the angle bracket form searches only places 2 and 3.

Even if the specifics vary (the syntax of the command-line flag
for rule 2, or the precise location(s) for rule 3), the general
pattern can usually be maintained.

Maintaining the pattern makes it easier to port large programs
which have made judicious use of the possibilities inherent on
the "usual rules."  (I labor under no miscomprehensions as to how
much variation is already out there, and how much a large program
may consequently have to be modified during porting.)  In
particular, it is nice to be able to port a large piece of
software by changing only the Makefile, not every #include line
in every source file.

Compiler implementers should keep "make"-like utilities firmly in
mind, making sure that both macro #definition (-D) and #include
path additions (-I) can be performed from the command line.  For
example, the VMS C compiler (VAX11C) allows the #include search
path to be modified using logical names, but not on the compiler
invocation line, making Makefiles considerably harder to write.

Make sure, also, that both the quote form and the angle bracket
form can make use of a search path (it's okay if it's the same
path).  The ability to have either form search for a header file
not in the #includer's directory is useful.

                                            Steve Summit
                                            scs@adam.pika.mit.edu