Twój kompilator właśnie próbował skompilować plik o nazwie foo.cc
. Po naciśnięciu numeru wiersza line
kompilator znajduje:
#include "bar"
lub
#include <bar>
Kompilator następnie próbuje znaleźć ten plik. W tym celu wykorzystuje zestaw katalogów do przeglądania, ale w tym zestawie nie ma pliku bar
. Aby uzyskać wyjaśnienie różnicy między wersjami instrukcji include, zajrzyj tutaj .
Jak powiedzieć kompilatorowi, gdzie go znaleźć
g++
ma opcję -I
. Umożliwia dodanie ścieżek wyszukiwania dołączania do wiersza poleceń. Wyobraź sobie, że twój plik bar
znajduje się w folderze o nazwie frobnicate
względem foo.cc
(załóżmy, że kompilujesz z katalogu, w którym foo.cc
się znajduje):
g++ -Ifrobnicate foo.cc
Możesz dodać więcej ścieżek włączania; każdy, który podajesz, odnosi się do bieżącego katalogu. Kompilator Microsoftu ma opcję korelacji, /I
która działa w ten sam sposób, lub w Visual Studio foldery można ustawić na stronach właściwości projektu, w sekcji Właściwości konfiguracji-> C / C ++ -> Ogólne-> Dodatkowe katalogi dołączane.
Teraz wyobraź sobie, że masz wiele wersji bar
w różnych folderach, biorąc pod uwagę:
#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;
}
Priorytet z #include "bar"
jest skrajnie lewy:
$ g++ -IA -IB -IC foo.cc
$ ./a.out
A/bar
Jak widać, gdy kompilator zaczął rozglądać się za pośrednictwem A/
, B/
oraz C/
, że zatrzymał się na pierwszym lub skrajnej lewej przeboju.
Dotyczy to obu form include <>
i incude ""
.
Różnica między #include <bar>
i#include "bar"
Zwykle #include <xxx>
najpierw sprawdza foldery systemowe, a najpierw #include "xxx"
bieżące lub niestandardowe foldery.
Na przykład:
Wyobraź sobie, że masz następujące pliki w folderze projektu:
list
main.cc
z main.cc
:
#include "list"
....
W tym celu kompilator umieści #include
plik list
w folderze projektu, ponieważ obecnie się kompiluje main.cc
i ten plik znajduje się list
w bieżącym folderze.
Ale z main.cc
:
#include <list>
....
a następnie g++ main.cc
Twój kompilator najpierw zajrzy do folderów systemowych, a ponieważ <list>
jest to standardowy nagłówek, będzie #include
to plik o nazwie list
dostarczonej z platformą C ++ jako część biblioteki standardowej.
To wszystko jest nieco uproszczone, ale powinno dać ci podstawowe pojęcie.
Szczegóły dotyczące <>
/ ""
-priorities i-I
Zgodnie z dokumentacją gcc , priorytet dla include <>
"normalnego systemu uniksowego" jest następujący:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
W przypadku programów w języku C ++ będzie również szukać najpierw w katalogu / usr / include / c ++ / version. W powyższym celu jest to nazwa kanoniczna systemu, dla którego skonfigurowano GCC do kompilowania kodu; […].
Dokumentacja podaje również:
Możesz dodać do tej listy za pomocą opcji wiersza poleceń -Idir. Wszystkie katalogi nazwane -I są przeszukiwane, w kolejności od lewej do prawej, przed katalogami domyślnymi . Jedynym wyjątkiem jest sytuacja, gdy katalog jest już przeszukiwany domyślnie. W takim przypadku opcja jest ignorowana, a kolejność wyszukiwania katalogów systemowych pozostaje niezmieniona.
Aby kontynuować nasz #include<list> / #include"list"
przykład (ten sam kod):
g++ -I. main.cc
i
#include<list>
int main () { std::list<int> l; }
i rzeczywiście, nadaje -I.
priorytet folderowi .
nad zawartością systemu i otrzymujemy błąd kompilatora.