Pour que le compilateur puisse compiler les fichiers séparément, il faut que vous respectiez les conditions suivantes :
chaque type ou variable utilisé doit être déclaré ;
toute fonction non déclarée doit renvoyer un entier (en C seulement, en C++, l'utilisation d'une fonction non déclarée génère une erreur).
Ces conditions ont des répercussions sur la syntaxe des programmes. Elles seront vues dans les paragraphes suivants.
Les types doivent toujours être définis avant toute utilisation dans un fichier source. Par exemple, il est interdit d'utiliser une structure client sans l'avoir définie avant sa première utilisation. Toutefois, il est possible d'utiliser un pointeur sur un type de donnée sans l'avoir complètement défini. Une simple déclaration du type de base du pointeur suffit en effet dans ce cas là.
Les variables qui sont définies dans un autre fichier doivent être déclarées avant leur première utilisation. Pour cela, on les spécifie comme étant des variables externes, avec le mot clé extern :
Inversement, si une variable ne doit pas être accédée par un autre module, il faut déclarer cette variable statique. Ainsi, même si un autre fichier utilise le mot clé extern, il ne pourra pas y accéder.
Lorsqu'une fonction se trouve définie dans un autre fichier, il est nécessaire de la déclarer. Pour cela, il suffit de donner sa déclaration (le mot clé extern est également utilisable, mais facultatif dans ce cas) :
Il faudra bien faire la distinction entre les fichiers compilés séparément et les fichiers inclus par le préprocesseur. Ces derniers ne sont en effet pas séparés : ils sont compilés avec les fichiers dans lesquels ils sont inclus. Il est donc possible d'inclure du code dans les fichiers d'en-tête.
Les programmes modulaires auront donc typiquement la structure suivante :
Fichier a.h #include Fichier b.c (déclaration des types et --------> (Utilisation des fonctions de a.c, des fonctions de a.c) déclarées dans le fichier inclus a.h) -------------- INDÉPENDANCE DES FICHIERS a.c ET b.c ----------------- Fichier a.h #include Fichier a.c --------> (définition des fonctions déclarées dans le fichier d'en-tête a.h) Compilation : a.c donne a.o, b.c donne b.o ; Édition de liens : a.o et b.o donnent le programme exécutable.
Le langage C++ donne la possibilité d'appeler des fonctions et d'utiliser des variables qui proviennent d'un module écrit dans un autre langage. Pour permettre cela, il dispose de directives permettant d'indiquer comment l'édition de liens doit être faite. La syntaxe permettant de réaliser cela utilise le mot clé extern, avec le nom du langage entre guillemets. Cette directive d'édition de liens doit précéder les déclarations de variables et de données concernées. Si plusieurs variables ou fonctions utilisent la même directive, elles peuvent être regroupées dans un bloc délimité par des accolades, avec la directive d'édition de liens placée juste avant ce bloc. La syntaxe est donc la suivante :
extern "langage" [déclaration | { déclaration [...] }]
Cependant, les seuls langages qu'une implémentation doit obligatoirement supporter sont les langages "C" et "C++". Pour les autres langages, aucune norme n'est définie et les directives d'édition de liens sont dépendantes de l'implémentation.
Dans l'exemple précédent, la compilation conditionnelle est utilisée pour n'utiliser la directive d'édition de liens que si le code est compilé en C++. Si c'est le cas, la variable EntierC et la fonction FonctionC sont déclarées au compilateur C++ comme étant des objets provenant d'un module C.
Précédent | Sommaire | Suivant |
Syntaxe des outils de compilation | Niveau supérieur | Comment faire du code illisible ? |