-1

I have a third party library which I want to include in my code, but the developer included all local header files via the <> syntax causing "No such file or directory" errors to occur while compiling.

If I manually change #include <a.h> to #include "a.h" the file in question compiles just fine. Only problem is, there are hundreds of files that include all types of headers via <>.

Is there a UNIX compiler directive to treat <> which it can't find as ""?

Solution:

After trying several things, I ended up using sed to replace all #include <XXX.h> with #include "XXX.h". Here is the command to change it for an entire directory:

find ./ -type f -exec sed -i -E "s/include <(.+).h>/include \"\1.h\"/g" {} \;

This worked for my specific case. I would not recommend replacing all header includes with "".

CompEng88
  • 1,336
  • 14
  • 25
  • 3
    How about writing a script to modify the files. Then it won't matter even if there were hundreds of thousands of them. – eerorika Mar 23 '17 at 21:19
  • 3
    Which compiler? `-I .` on Posix-y platforms has a chance. Similarly `/I=.` on Windows. See [this question](http://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename) (which is not a duplicate) for more details – Martin Bonner supports Monica Mar 23 '17 at 21:22
  • 4
    Note that the behaviour of both <> and "" enclosed include directives are implementation defined. You'll have to specify which compiler you are using. – eerorika Mar 23 '17 at 21:23
  • 1
    Why not just add the relevant folder(s) to the compiler's includes path configuration? That would let `<>` handle them normally. I have a feeling the 3rd party developer probably wants you to do that anyway, or else they would have used `""` to begin with. – Remy Lebeau Mar 23 '17 at 21:33
  • Although the behaviour of `#include ` and `#include "a.h"` are implementation defined, it is defined in the standard that if the search for `"a.h"` fails, it falls back on the search for ``. That is, double quotes may look in extra places compared to angle brackets, but not vice versa. – Jonathan Leffler Mar 23 '17 at 22:19

2 Answers2

1

While including Header Files (or Libraries) in a C\C++ Program. There are two ways for doing this:

1). Writing the file name in quotes (such as #include "a.h" )
2). Writing the file name in angle brackets (such as #include<a.h>)

But both are different from each other, the first method #include"a.h" first searches the file in current directory of your program and then searches in C++ library. Whereas, on the other hand, #include<a.h> only looks in the default C++ library if the file exists , other wise compiler gives error.

I think in your case, the "a.h" file is in your program's current directory that's why #include"a.h" is working and <a.h> is not working. If you want it that way, just copy the file and paste it in your compiler's directory where other built-in header files are located. You can simply search for "stdio.h" in explorer then open the folder containing file and paste "a.h" in that folder. Then try using #include<a.h> it will work fine. I hope that answers the question.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
HN Learner
  • 544
  • 7
  • 19
0

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:

-Idirectory

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Just for completeness, `#include ` does not require `a.h` to be the name of a file. It requires a "header", while `#include "a.h"` requires a "file". This allows implementations to implement standard headers in implementation-specific binary forms. Of course, if `a.h` is, in fact, a file, it will work equally well with either form, assuming that the search paths have been set appropriately. – Pete Becker Mar 24 '17 at 11:21