Вопрос: В чем разница между #include и #include "filename"?


В языках программирования C и C ++ в чем разница между использованием угловых скобок и использованием котировок в includeзаявление следующим образом?

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

1774


источник


Ответы:


На практике разница в том, где препроцессор выполняет поиск включенного файла.

Для #include <filename>препроцессор выполняет поиск зависимым от реализации образом, обычно в каталогах поиска, предварительно назначенных компилятором / IDE. Этот метод обычно используется для включения стандартных файлов заголовков библиотек.

Для #include "filename"препроцессор выполняет поиск сначала в том же каталоге, что и файл, содержащий директиву, а затем следует путь поиска, используемый для #include <filename>форма. Этот метод обычно используется для включения файлов заголовков, определенных программистом.

Более полное описание доступно в GCC документация по путям поиска ,


1015



Единственный способ узнать, это прочитать документацию вашей реализации.

В стандарт C , в разделе 6.10.2, параграфы 2-4:

  • Директива предварительной обработки формы

    #include <h-char-sequence> new-line
    

    ищет последовательность мест, определенных для реализации, для заголовка, идентифицированного однозначно указанной последовательностью между <а также >разделителей и вызывает замену этой директивы на все содержимое заголовка. Как указано места, или идентифицированный заголовок определяется реализацией.

  • Директива предварительной обработки формы

    #include "q-char-sequence" new-line
    

    вызывает замену этой директивы всем содержимым исходного файла, идентифицированного указанной последовательностью между "разделители. Именованный исходный файл выполняется поисковым способом. Если этот поиск не поддерживается или если поиск не выполняется, директива перерабатывается так, как если бы она была прочитана

    #include <h-char-sequence> new-line
    

    с идентичной содержащейся последовательностью (в том числе >символы, если они есть) от оригинала   директивы.

  • Директива предварительной обработки формы

    #include pp-tokens new-line
    

    (который не соответствует одной из двух предыдущих форм) разрешен. Точки предварительной обработки после includeв директиве обрабатываются так же, как в обычном тексте. (Каждый идентификатор, который в настоящее время определяется как имя макроса, заменяется его списком замещения токенов предварительной обработки.) Директива, полученная после всех замен, должна соответствовать одной из двух предыдущих форм. Способ, с помощью которого последовательность предпроцессорных токенов между <и >пара токенов предварительной обработки или пара "символы объединяются в один заголовок, а токен предварительной обработки - это реализация.

Определения:

  • h-char: любой член набора символов источника, кроме символа новой строки и >

  • q-char: любой член набора символов источника, кроме символа новой строки, и "


588



Последовательность символов между <и> однозначно относится к заголовку, который не обязательно является файлом. Реализации в значительной степени свободны использовать последовательность символов по своему усмотрению. (В основном, однако, просто рассматривайте его как имя файла и выполните поиск в включить путь , как утверждают другие должности.)

Если #include "file"форма используется, реализация сначала ищет файл с заданным именем, если поддерживается. Если нет (поддерживается) или если поиск не выполняется, реализация ведет себя так, как если бы другая ( #include <file>).

Кроме того, существует третья форма и используется, когда #includeдиректива не соответствует ни одной из вышеперечисленных форм. В этой форме выполняется некоторая базовая предварительная обработка (например, макрорасширение) на «операндах» #includeи результат, как ожидается, будет соответствовать одной из двух других форм.


208



Некоторые хорошие ответы здесь содержат ссылки на стандарт C, но забыли стандарт POSIX, особенно специфическое поведение c99 (например, компилятор C) команда.

В соответствии с Базовые спецификации Open Group Issue 7 ,

каталог

Измените алгоритм поиска заголовков, имена которых не являются абсолютными путями для поиска в каталоге, названном каталог путь, прежде чем смотреть в обычные места. Таким образом, заголовки, имена которых заключены в двойные кавычки («»), сначала выполняются поиск в каталоге файла с помощью #включают line, затем в каталогах, названных в варианты и последние в обычных местах. Для заголовков, имена которых заключены в угловые скобки («<>»), заголовок должен искать только в каталогах, названных в а затем в обычных местах. Каталоги, названные в параметры должны быть найдены в указанном порядке. Реализации должны поддерживать не менее десяти экземпляров этой опции в одном c99 вызов команды.

Таким образом, в среде, совместимой с POSIX, с C-компилятором, совместимым с POSIX, #include "file.h"скорее всего, будет искать ./file.hво-первых, где .это каталог, в котором находится файл с #includeв то время как #include <file.h>, скорее всего, будет искать /usr/include/file.hво-первых, где /usr/includeопределяется ваша система обычные места для заголовков (это не определено POSIX).


90



Оно делает:

"mypath/myfile" is short for ./mypath/myfile

с .являющийся либо каталогом файла, в котором #includeсодержится в и / или текущем рабочем каталоге компилятора и / или default_include_paths

а также

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

Если ./в <default_include_paths>, то это не имеет значения.

Если mypath/myfileнаходится в другом каталоге include, поведение не определено.


35



GCC documentation says the following about the difference between the two:

Both user and system header files are included using the preprocessing directive ‘#include’. It has two variants:

#include <file>

This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option (see Invocation).

#include "file"

This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option. The argument of ‘#include’, whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus, #include <x/*y> specifies inclusion of a system header file named x/*y.

However, if backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus,#include "x\n\\y"specifies a filename containing three backslashes. (Some systems interpret ‘\’ as a pathname separator. All of these also interpret ‘/’ the same way. It is most portable to use only ‘/’.)

It is an error if there is anything (other than comments) on the line after the file name.


29



The <file> include tells the preprocessor to search in -I directories and in predefined directories first, then in the .c file's directory. The "file" include tells the preprocessor to search the source file's directory first, and then revert to -I and predefined. All destinations are searched anyway, only the order of search is different.

The 2011 standard mostly discusses the include files in "16.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.

Note that "xxx" form degrades to <xxx> form if the file is not found. The rest is implementation-defined.


23



By the standard - yes, they are different:

  • 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.

  • 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.

  • A preprocessing directive of the form

    #include pp-tokens new-line
    

    (that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.

Definitions:

  • h-char: any member of the source character set except the new-line character and >

  • q-char: any member of the source character set except the new-line character and "

Note that the standard does not tell any relation between the implementation-defined manners. The first form searches in one implementation-defined way, and the other in a (possibly other) implementation-defined way. The standard also specifies that certain include files shall be present (for example, <stdio.h>).

Formally you'd have to read the manual for your compiler, however normally (by tradition) the #include "..." form searches the directory of the file in which the #include was found first, and then the directories that the #include <...> form searches (the include path, eg system headers).


16



Thanks for the great answers, esp. Adam Stelmaszczyk and piCookie, and aib.

Like many programmers, I have used the informal convention of using the "myApp.hpp" form for application specific files, and the <libHeader.hpp> form for library and compiler system files, i.e. files specified in /I and the INCLUDE environment variable, for years thinking that was the standard.

However, the C standard states that the search order is implementation specific, which can make portability complicated. To make matters worse, we use jam, which automagically figures out where the include files are. You can use relative or absolute paths for your include files. i.e.

#include "../../MyProgDir/SourceDir1/someFile.hpp"

Older versions of MSVS required double backslashes (\\), but now that's not required. I don't know when it changed. Just use forward slashes for compatibility with 'nix (Windows will accept that).

If you are really worried about it, use "./myHeader.h" for an include file in the same directory as the source code (my current, very large project has some duplicate include file names scattered about--really a configuration management problem).

Here's the MSDN explanation copied here for your convenience).

Quoted form

The preprocessor searches for include files in this order:

  1. In the same directory as the file that contains the #include statement.
  2. In the directories of the currently opened include files, in the reverse order in which
    they were opened. The search begins in the directory of the parent include file and
    continues upward through the directories of any grandparent include files.
  3. Along the path that's specified by each /I compiler option.
  4. Along the paths that are specified by the INCLUDE environment variable.

Angle-bracket form

The preprocessor searches for include files in this order:

  1. Along the path that's specified by each /I compiler option.
  2. When compiling occurs on the command line, along the paths that are specified by the INCLUDE environment variable.

12