标签云

微信群

扫码加入我们

WeChat QR Code

In the C and C++ programming languages, what is the difference between using angle brackets and using quotes in an include statement, as follows?

  1. #include <filename>
  2. #include "filename"


gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC6

2018年08月14日48分55秒

Where Does GCC Look to Find its Header Files

2018年08月15日48分55秒

The statement: "the preprocessor searches in the same directory..." may be true in practice but the standard states that the named source file is "searched for in an implementation-defined manner". See answer from piCookie.

2018年08月14日48分55秒

While your answer may appear to be "true", because this is how many implementations work by convention, you should take a close look at aib's and piCookie's answers. They both point out (backed by the wording of the C standard) that the real distinction is inclusion of a "header" versus inclusion of a "source file" (and no, this doesn't mean ".h" vs. ".c"). "Source file" in this context can be (and usually is, and almost always should be) a ".h" file. A header does not necessarily need to be a file (a compiler could e.g. include a header that is statically coded, not in a file).

2018年08月14日48分55秒

"... the preprocessor searches in the same directory as the file being compiled for the file to be included." This statement is not completely correct. I was interested in this question because I was curious what the actual answer is, but I know this is not true because at least with gcc when you specify an additional include path with -I that will search for files specified with #include "filename.h"

2018年08月15日48分55秒

Those who don't like the answer, please, give one practical example, where it is wrong.

2018年08月15日48分55秒

Sure enough, I recently mixed these syntaxes when including headers from 'the same' library and ended up with redefinition errors. If I understand correctly, #include <...> used the package installed on the system and #include "..." used the nearby repository version. I might have those backwards. Either way, the include guard in the packaged header is prefixed with an underscore. (It could be a convention for packages or maybe a way to deliberately prevent mixing the two, although version qualifiers would make more sense to me.)

2018年08月14日48分55秒

Relevant: implementation in g++ and in visual c++

2018年08月14日48分55秒

piCookie both <filename> and "filename" search for implementation-defined places. So what is the difference ?

2018年08月15日48分55秒

Stefan, I'm just quoting the standard which does not say anything about INCLUDE_PATH. Your implementation may do that, and mine may not. The original question was generically C and not specifically gcc (which I don't think uses INCLUDE_PATH) or Microsoft C (which I think does) or any other, so it can not be answered generically but instead each implementation's documentation must be referenced.

2018年08月14日48分55秒

As with all of these situations, concrete examples (especially of common scenarios) are greatly useful and equally appreciated. Needlessly obtuse generic answers don't have as much practical use.

2018年08月15日48分55秒

"Here's how the C standard can be verbose and not answer your question"

2018年08月15日48分55秒

+1, this is probably the most concise and correct answer here. According to the standard (which piCookie quotes from in his answer), the only real difference is "header" versus "source file". The search mechanism is implementation-defined either way. Using double quotes means that you intend to include a "source file", while angle brackets mean you intend to include a "header" which, as you say, may not be a file at all.

2018年08月14日48分55秒

See Dan Moulding's comment to quest49's answer; standard headers don't have to be in file form, they can be built-in.

2018年08月14日48分55秒

I've been reading this "standard headers don't have to be in file form" for a decade. Care to provide a real-world example?

1970年01月01日00分03秒

Maxim Yegorushkin: I can't think of any existing real-world examples either; however, no complete C11 compiler can exist for MS-DOS unless headers don't have to be files. This is because some of the C11 header names are not compatible with the "8.3" MS-DOS file name limitation.

2018年08月14日48分55秒

MaximEgorushkin: The VAX/VMS C compiler kept all the C runtime library headers in a single textual library file (similar to a unix archive), and used the string between the < and > as the key to index into the library.

2018年08月14日48分55秒

What is exact source of the text? Is it from normative part of IEEE Std 1003.1, 2013?

2018年08月15日48分55秒

osgx: that wording (or something extremely similar) is found in the POSIX specification for c99 — which is the POSIX name for the C compiler. (The POSIX 2008 standard could hardly refer to C11; the 2013 update to POSIX 2008 did not change the C standard that it referred to.)

2018年08月15日48分55秒

No, #include "mypath/myfile" is not equivalent to #include "./mypath/myfile". As piCookie's answer says, double quotes tell the compiler to search in an implementation-defined manner -- which includes searching in the places specified for #include <...>. (Actually, it probably is equivalent, but only because, for example, /usr/include/mypath/myfile can be referred to as /usr/include/./mypath/myfile -- at least on Unix-like systems.)

2018年08月14日48分55秒

Keith Thompson: That's right, I was thinking of my Linux box. Evidently it could be different. Though in practice, Windows as non-Posix operating system also does interprete / as path separator, and ./ also exists.

2018年08月15日48分55秒

the -L dirpath option then adds dirpath to the defaultincludepaths, as opposed to giving another meaning to the . (as referred to above). This has the expected consequence that both #include "..." and #include <...> search in dirpath

2018年08月14日48分55秒

I think this answer is incorrect, since it implies that headers included with double quotes are always looked for in the current working directory. The search mechanism is way more detailed; this answer is incomplete. I'm not adding this comment to complain or whine, but because the system asks me to add a comment to explain why I voted this answer down.

2018年08月14日48分55秒

Could you provide a reference to where in the C standard this -I business is specified?

2018年08月14日48分55秒

juanchopanza done. See also the top answer :)

2018年08月15日48分55秒

I see no reference to -I.

2018年08月14日48分55秒

That's "implementation-defined" part.

2018年08月15日48分55秒

Sigh. I your answer, you make it sound like that is something specified in the language.

2018年08月14日48分55秒

This is mostly just the same text as piCookie's answer from seven years earlier.

2018年08月15日48分55秒

KyleStrand That's because the same text is a quote of the relevant section in the standard - that text should be identical. The actual answer is not the same text and is somewhat different - while I also recognize that it will be written in the documentation for the implementation I also note that there's also a traditional way these are interpreted (that most or all compilers I used respects).

2018年08月14日48分55秒

IMO this is the best answer here, because it covers both what the standard says and what most compilers actually do.

2018年08月14日48分55秒

Not sure why people disagree.

2018年08月14日48分55秒

I suspect that's because most people compile only the files in their CWD. If you're in directory foo, and you're compiling foo/unittest/bar.c, and it includes bar.h, then "bar.h" works and <bar.h> does not.

2018年08月15日48分55秒

Maxim people disagree because the behaviour you describe is not standard C.

2018年08月14日48分55秒

Spookbuster Right, the standard says both <filename> and "filename" search for implementation-defined places.

2018年08月15日48分55秒

However, using angle brackets or quotes doesn't affect the way the files are included, it is exactly the same: the preprocessor essentally creates a large source file by copy'n'pasting the code from include files to original source file, before giving it to the compiler (preprocessor does other thing, like #define sustitution, #if evaluation, etc. but the #include processing is that easy)

2018年08月14日48分55秒

What about conflicts? eg say I have zlib.h in my 'user' search paths, and a different version exists in the system search path, then does #include <zlib.h> include the system version and #include "zlib.h" include my own?

2018年08月15日48分55秒

Aha, answered my own question: stackoverflow.com/questions/21593/…

2018年08月14日48分55秒

Thank you for acknowledging that both the standard(s) and typical implementation conventions are both relevant here, rather than simply stating that it's unknowable because it's not specified by the standard.

2018年08月15日48分55秒

Can you show me where the restriction inside your () is defined?

2018年08月14日48分55秒

after reading 16.2.7, it seems as if this a recommendation, not requirement for strict conformance. my bad.

2018年08月14日48分55秒

Which new information adds this answer to the other ones?

2018年08月14日48分55秒

This is an over-simplification of the issue — and not 100% accurate, therefore. There are better answers.

2018年08月15日48分55秒

Doesn't <XXX.h> only search the standard headers?

2018年08月15日48分55秒

PeterMortensen not only the standard headers but alose -L headers in gcc

2018年08月14日48分55秒

This answer is not useful. It isn't sufficiently accurate or nuanced. The comment about "-L headers" is peculiar; the -L option specifies where libraries can be found, not headers.

2018年08月15日48分55秒

There's a fair amount of truth to this, but the answer isn't nuanced enough and doesn't cover all the points that the higher-voted answers cover. It isn't a helpful addition.

2018年08月15日48分55秒

That is an over-simplification of the answer (and therefore somewhat inaccurate), and the existing answers are better.

2018年08月15日48分55秒