Ваш компілятор щойно спробував скомпілювати названий файл 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. У наведеному вище ціль - це канонічна назва системи GCC, налаштованої на компіляцію коду для; [...].
У документації також зазначено:
Ви можете додати до цього списку за допомогою опції командного рядка -Idir. Всі каталоги з іменем -I шукаються в порядку зліва направо перед каталогами за замовчуванням . Єдиним винятком є випадки, коли каталог за замовчуванням вже шукається. У цьому випадку параметр ігнорується, а порядок пошуку системних каталогів залишається незмінним.
Щоб продовжити наш #include<list> / #include"list"приклад (той самий код):
g++ -I. main.cc
і
#include<list>
int main () { std::list<int> l; }
і справді, -I.пріоритети папки .над системою включають, і ми отримуємо помилку компілятора.