Ваш компилятор только что попытался скомпилировать файл с именем 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
в разных папках, учитывая:
#include<string>
std::string which() { return "A/bar"; }
#include<string>
std::string which() { return "B/bar"; }
#include<string>
std::string which() { return "C/bar"; }
#include "bar"
#include <iostream>
int main () {
std::cout << which() << std::endl;
}
Приоритет с #include "bar"
крайним левым:
$ g++ -IA -IB -IC foo.cc
$ ./a.out
A/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
Для программ на C ++ он также сначала будет искать в / usr / include / c ++ / version. В приведенном выше примере target - это каноническое имя системы, для которой GCC был настроен для компиляции кода; [...].
В документации также указано:
Вы можете добавить в этот список параметр командной строки -Idir. Все каталоги, названные -I, ищутся в порядке слева направо перед каталогами по умолчанию . Единственное исключение - когда dir уже ищется по умолчанию. В этом случае опция игнорируется, и порядок поиска для системных каталогов остается неизменным.
Чтобы продолжить наш #include<list> / #include"list"
пример (тот же код):
g++ -I. main.cc
а также
#include<list>
int main () { std::list<int> l; }
и действительно, -I.
папка имеет приоритет .
над системой, и мы получаем ошибку компилятора.