Ваш компилятор только что попытался скомпилировать файл с именем 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.папка имеет приоритет .над системой, и мы получаем ошибку компилятора.