Votre compilateur vient d'essayer de compiler le fichier nommé foo.cc
. En frappant le numéro de ligne line
le compilateur trouve :
#include "bar"
o
#include <bar>
Le compilateur essaie alors de trouver ce fichier. Pour cela, il utilise un ensemble de répertoires à consulter, mais dans cet ensemble, il n'existe pas de fichier bar
. Pour une explication des différences entre les versions de l'instruction include, voir aquí .
Comment indiquer au compilateur où le trouver ?
g++
a une option -I
. Il vous permet d'ajouter des chemins de recherche d'inclusion à la ligne de commande. Imaginez que votre fichier bar
se trouve dans un dossier nommé frobnicate
par rapport à foo.cc
(en supposant que vous compilez à partir du répertoire où se trouve l'application foo.cc
est situé) :
g++ -Ifrobnicate foo.cc
Vous pouvez ajouter plus de chemins d'inclusion ; chacun que vous donnez est relatif au répertoire courant. Le compilateur de Microsoft a une option correspondante /I
qui fonctionne de la même manière, ou dans Visual Studio, les dossiers peuvent être définis dans les pages de propriétés du projet, sous Configuration Properties->C/C++->General->Additional Include Directories.
Imaginez maintenant que vous avez plusieurs versions de bar
dans des dossiers différents, donnés :
// A/bar
#include<string>
std::string which() { return "A/bar"; }
// B/bar
#include<string>
std::string which() { return "B/bar"; }
// C/bar
#include<string>
std::string which() { return "C/bar"; }
// foo.cc
#include "bar"
#include <iostream>
int main () {
std::cout << which() << std::endl;
}
La priorité avec #include "bar"
est le plus à gauche :
$ g++ -IA -IB -IC foo.cc
$ ./a.out
A/bar
Comme vous pouvez le voir, lorsque le compilateur a commencé à regarder à travers A/
, B/
y C/
il s'est arrêté au premier coup ou au coup le plus à gauche.
Ceci est vrai pour les deux formes, include <>
y incude ""
.
Différence entre #include <bar>
y #include "bar"
Habituellement, le #include <xxx>
fait en sorte qu'il regarde d'abord dans les dossiers du système, l'option #include "xxx"
permet de regarder d'abord dans le dossier actuel ou dans le dossier personnalisé.
Par exemple :
Imaginez que vous avez les fichiers suivants dans votre dossier de projet :
list
main.cc
avec main.cc
:
#include "list"
....
Pour cela, votre compilateur #include
le fichier list
dans votre dossier de projet, car il compile actuellement main.cc
et il y a ce fichier list
dans le dossier en cours.
Mais avec main.cc
:
#include <list>
....
et ensuite g++ main.cc
votre compilateur regardera d'abord dans les dossiers du système, et parce que <list>
est un en-tête standard, il #include
le fichier nommé list
qui fait partie de la bibliothèque standard de votre plate-forme C++.
Tout ceci est un peu simplifié, mais devrait vous donner l'idée de base.
Détails sur <>
/ ""
-priorités et -I
Selon le Documentation gcc la priorité pour include <>
est, sur un "système Unix normal", le suivant :
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
Pour les programmes C++, il cherchera également dans /usr/include/c++/version, en premier lieu. Dans l'exemple ci-dessus, target est le nom canonique du système pour lequel GCC a été configuré pour compiler du code ; [...].
La documentation indique également :
Vous pouvez ajouter à cette liste avec l'option de ligne de commande -Idir. Tous les répertoires nommés par -I sont recherchés, dans l'ordre de gauche à droite, avant les répertoires par défaut . La seule exception est lorsque dir est déjà recherché par défaut. Dans ce cas, l'option est ignorée et l'ordre de recherche des répertoires système reste inchangé.
Pour poursuivre notre #include<list> / #include"list"
exemple (même code) :
g++ -I. main.cc
et
#include<list>
int main () { std::list<int> l; }
et en effet, le -I.
donne la priorité au dossier .
sur les inclusions du système et nous obtenons une erreur de compilation.
4 votes
Bel ajout à la FAQ. Merci à vous !