Formally, the C11 standard (ISO/IEC 9899:2011) says:
6.10.2 Source file inclusion
…
2 A preprocessing directive of the form
# include <
h-char-sequence
>
new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the <
and >
delimiters, and causes the replacement of that
directive by the entire contents of the header. How the places are specified or the header
identified is implementation-defined.
3 A preprocessing directive of the form
# include "
q-char-sequence
"
new-line
causes the replacement of that directive by the entire contents of the source file identified
by the specified sequence between the "
delimiters. The named source file is searched
for in an implementation-defined manner. If this search is not supported, or if the search
fails, the directive is reprocessed as if it read
# include <
h-char-sequence
>
new-line
with the identical contained sequence (including >
characters, if any) from the original directive.
Thus, the <header.h>
notation causes the preprocessor to search for the header in an implementation-defined way. The "header.h"
notation causes the preprocessor to search for the header in a possibly different implementation-defined way, and if that search fails, then it searches using the same search as it would have used for <header.h>
.
Thus, the quoted notation never looks in fewer places than the angle-bracket notation — but the angle-bracket notation may look in fewer places than the quoted notation.
With many compilers (preprocessors), the -I
option specifies extra places (directories) to be searched for headers. Those places are normally searched before the default locations. Also, very often the preprocessor will look for headers in either the current directory or the directory containing the source file or the current header file for nested #include
operations, or both. The rules are often a bit convoluted for reasons of backwards compatibility.
For example, the POSIX specification for the c99
compiler says:
-I
directory
Change the algorithm for searching for headers whose names are not absolute pathnames to look in the directory named by the directory pathname before looking in the usual places. Thus, headers whose names are enclosed in double-quotes (""
) shall be searched for first in the directory of the file with the #include
line, then in directories named in -I
options, and last in the usual places. For headers whose names are enclosed in angle brackets (<>
), the header shall be searched for only in directories named in -I
options and then in the usual places. Directories named in -I
options shall be searched in the order specified. If the -I
option is used to specify a directory that is one of the usual places searched by default, the results are unspecified. Implementations shall support at least ten instances of this option in a single c99
command invocation.
Microsoft will have its own version of these rules.
To resolve the problem in the question, you either need to change the notation from #include <a.h>
to #include "a.h"
, or you need to install the header in a directory where it will be found anyway (e.g. /usr/local/include
on many Unix-like systems). If neither of those is acceptable, you will need to specify the directory where a.h
is stored on the compiler command line — using -I.
on Unix-based systems, for example.
There might be a way to configure your compiler to look in extra directories without needing the command line option. Such techniques are very compiler-dependent, though. You should either change the notation used (angle brackets to quotes) or add the option to the compiler command line.