g++
дает мне ошибки формы:
foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
То же самое и при компиляции C-программ с использованием gcc
.
Почему это?
Обратите внимание: этот вопрос задавали много раз раньше, но каждый раз он относился к ситуации, в которой спрашивает. Цель этого вопроса состоит в том, чтобы задать вопрос, который другие могут быть закрыты как дубликаты раз и навсегда; FAQ .
Ответы:
Ваш компилятор только что попытался скомпилировать файл с именем
foo.cc
. При достижении номера строкиline
компилятор находит:#include "bar"
или
#include <bar>
Затем компилятор пытается найти этот файл. Для этого он использует набор каталогов, но в этом наборе нет файла
bar
. Объяснение разницы между версиями оператора include см . Здесь .Как сообщить компилятору, где его найти
g++
есть возможность-I
. Он позволяет добавлять пути поиска в командную строку. Представьте, что ваш файлbar
находится в папке с именемfrobnicate
относительноfoo.cc
(предположим, что вы компилируете из каталога, в которомfoo.cc
он находится):g++ -Ifrobnicate foo.cc
Вы можете добавить больше включаемых путей; каждый, который вы указываете, относится к текущему каталогу. Компилятор Microsoft имеет параметр корреляции,
/I
который работает таким же образом, или в Visual Studio папки можно установить на страницах свойств проекта в разделе Свойства конфигурации-> C / C ++ -> Общие-> Дополнительные каталоги включения.Теперь представьте, что у вас есть несколько версий
bar
в разных папках, учитывая:// A/bar #include<string> std::string which() { return "A/bar"; }
// B/bar #include<string> std::string which() { return "B/bar"; }
// C/bar #include<string> std::string which() { return "C/bar"; }
// foo.cc #include "bar" #include <iostream> int main () { std::cout << which() << std::endl; }
Приоритет с
#include "bar"
крайним левым:Как видите, когда компилятор начал просмотр
A/
,B/
иC/
он остановился при первом или крайнем левом ударе.Это верно как для форм, так
include <>
и дляincude ""
.Разница между
#include <bar>
и#include "bar"
Обычно
#include <xxx>
он сначала просматривает системные папки, а#include "xxx"
затем - текущие или пользовательские папки.Например:
Представьте, что у вас в папке проекта есть следующие файлы:
list main.cc
с
main.cc
:#include "list" ....
Для этого ваш компилятор поместит
#include
файлlist
в папку вашего проекта, потому что он в настоящее время компилируетсяmain.cc
и этот файл находитсяlist
в текущей папке.Но с
main.cc
:#include <list> ....
а затем
g++ main.cc
ваш компилятор сначала изучит системные папки, и, поскольку<list>
это стандартный заголовок, он найдет#include
файл с именем,list
который поставляется с вашей платформой C ++ как часть стандартной библиотеки.Все это немного упрощено, но должно дать вам основную идею.
Подробная информация о
<>
/""
-приоритетах и-I
Согласно документации gcc , приоритет для
include <>
"нормальной системы Unix" следующий:/usr/local/include libdir/gcc/target/version/include /usr/target/include /usr/include
В документации также указано:
Чтобы продолжить наш
#include<list> / #include"list"
пример (тот же код):g++ -I. main.cc
а также
#include<list> int main () { std::list<int> l; }
и действительно,
-I.
папка имеет приоритет.
над системой, и мы получаем ошибку компилятора.источник
#include <>
смотрит в каталогах, перечисленных-I
перед системными каталогами по умолчанию-I
относятся к каталогу, в котором вы запускаете gcc, а не относительно компилируемого файла. Разница значительна, если вы это сделаетеg++ -Ifrobnicate blah/foo.cc
PATH
переменной окружения (в системах Linux) на то, как компилятор вообще ищет файлы?