0

Which file is preferred when there are two files with the same specified name: the first is in the directory in which the file which includes it lies, and the second is somewhere else but its directory is in include path?

E.g.: (where proj_dir is in include path)

.
└── proj_dir
    ├── a
    │   ├── a.c -> #include "b.h"
    │   └── b.h
    └── b.h

Does anything change when a is also in the include path?

  • 2
    The location where the preprocessor will search for `#include`d files is implementation defined. Typically, `#include "b.h"` does search in the current directory first, but the standard doesn't require that. With most compilers, there are options (e.g. include path, environment variables) that can affect what happens. You'll need to read the documentation for your compiler to be 100% certain. Or test it - do something detectably different in the two versions of `"b.h"` (like each defining a different macro, and then checking in `a.c`. which macro is defined). – Peter Aug 05 '20 at 11:29
  • The priority depends on the compiler, because it is implementation defined. What compiler are you using? – Eljay Aug 05 '20 at 12:47

1 Answers1

2

When including files using double-quotes " then the preprocessor will look first in the same directory as the file doing the including.

In your case, if the file proj_dir/a/a.c have:

#include "b.h"

then it will include the proj_dir/a/b.h file.

If no file is found in the same directory, then the preprocessor will look through the include paths.


If including using angle brackets <> then the preprocessor will look first in the include paths.

Also note that the preprocessor will look in each include path in the order specified, and stop looking at first hit. So if you have an include file that is in multiple include paths, only the first one found will be included. So the order in which you add paths to search matter.


While this behavior is really implementation defined (as mentioned in a comment), the general behavior from the major implementations doesn't deviate very much from this.

The only deviation is really how system include paths are added. MSVC (for example) have multiple options to add include paths, and they are search in a specific order. While GCC have a preconfigured list of system directories that are searched first.

But as for the behavior of double-quoted inclusion, all implementations uses the directory of the current file first.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I suppose it's in the standard. Could you provide a reference to the appropriate clause in the standard (C or C++, since C++ surely inherits the rules from C)? – Adler Amorette Aug 05 '20 at 11:22
  • @AdlerAmorette I don't have reference to the specification directly available, but please see [this `#include` directive reference](https://en.cppreference.com/w/c/preprocessor/include). – Some programmer dude Aug 05 '20 at 11:24
  • 1
    @AdlerAmorette `Could you provide a reference to` In the standard it's all "implementation-defined". https://port70.net/~nsz/c/c11/n1570.html#6.10.2p3 – KamilCuk Aug 05 '20 at 11:26
  • Definitively implementation defined; GCC and MSVC for example handle this slightly different; https://stackoverflow.com/q/335408/1116364 , https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html – Daniel Jour Aug 05 '20 at 11:28
  • 1
    This answer refers to “the include paths” without first saying what those are. Allusions to undefined terms are often confusing for people who are not yet familiar with the concepts. It would be clearer to explain concepts first, that, typically, a compiler has a list of paths in the file system where it searches for files included with `#include "name"` and a list of paths where it searches for files included with `#include `, and that those lists are typically configurable with compiler switches (and with defaults when building/installing the compiler), and so on. – Eric Postpischil Aug 05 '20 at 11:47
  • Eric is right. There seem to be a misunderstanding going on here. OP seems to think that the compiler would go "*up* an include path", which means that s/he thinks the compiler would search in directory `a`, directory `proj_dir` and all the way up to the root and then there would be a conflict having two files with the same name but this is not the case. At least not in a default or automatic manner. – RobertS supports Monica Cellio Aug 05 '20 at 12:03
  • @AdlerAmorette You can find references from the C standard in [this answer](https://stackoverflow.com/a/77092/12139179). – RobertS supports Monica Cellio Aug 05 '20 at 12:05
  • 1
    @RobertSsupportsMonicaCellio, this is very rude to assume what one thinks. And as a matter of fact, you came to a wrong conclusion. – Adler Amorette Aug 05 '20 at 12:07
  • @AdlerAmorette No, it's not rude. It's what your question suggests. If that is not true, please clarify your question so that I can understand what you mean exactly. – RobertS supports Monica Cellio Aug 05 '20 at 12:09
  • @AdlerAmorette "*C or C++, since C++ surely inherits the rules from C*" - C and C++ are very different languages. You cannot expect that anything in C works in C++ and vice versa without having the proof. – RobertS supports Monica Cellio Aug 05 '20 at 12:17