Twój kompilator właśnie próbował skompilować plik o nazwie foo.cc. Po naciśnięciu numeru wiersza linekompilator 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 barznajduje się w folderze o nazwie frobnicatewzględem foo.cc(załóżmy, że kompilujesz z katalogu, w którym foo.ccsię 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, /Iktó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 barw 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 #includeplik listw folderze projektu, ponieważ obecnie się kompiluje main.cci ten plik znajduje się listw bieżącym folderze.
Ale z main.cc:
#include <list>
....
a następnie g++ main.ccTwój kompilator najpierw zajrzy do folderów systemowych, a ponieważ <list>jest to standardowy nagłówek, będzie #includeto plik o nazwie listdostarczonej 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.