Objets externes ou statiques

Un objet comme une fonction, une variable, etc., peut être automatique, dynamique, statique ou externe. Nous connaissons déjà les variables automatiques et dynamiques. Nous nous intéressons ici plutôt aux variables définies en dehors d’une fonction, et aux fonctions elles-mêmes.

Si l’on souhaite qu’un tel objet soit utilisable dans tous les fichiers du projet, il faut le déclarer externe, en utilisant le mot-clé extern. Si l’on préfère que l’objet ne soit utilisable que pour les fonctions du fichier courant, il faut le déclarer statique avec le mot-clé static. Les fonctions, définitions de types et variables sont externes par défaut, les constantes statiques.

Imaginons par exemple que le fichier iosfract.cpp ait besoin de partager avec le programme principal mainfra.cpp une variable globale glob (indiquant par exemple la dernière erreur d’entrée-sortie produite). Dans ce cas, on n’écrira pas, dans le fichier iosfract.h :

int glob = 1;

sinon la variable serait dupliquée en deux exemplaires différents dans les deux fichiers objets (ce qui n’est pas le but recherché), et l’éditeur de liens signalerait une erreur. Il faut indiquer explicitement au compilateur que la variable glob est partagée entre deux fichiers objets, et que c’est l’éditeur de liens qui s’en occupera. Il faut donc placer dans le fichier d’en-tête une déclaration externe :

extern int glob;

sans initialisation, et dans l’un des deux fichiers objets (n’importe lequel) une déclaration statique avec initialisation (explicite ou implicite puisque les objets statiques sont toujours initialisés) de l’objet :

mainfra.cpp

#include "iosfract.h"				int glob = 1;				// ...

 

Ainsi, chaque fois que l’on fait référence à glob dans iosfract.cpp, le compilateur sait que la variable est en fait ailleurs, et place un lien que l’éditeur de liens se chargera de résoudre.

Lorsqu’un objet est externe, il ne doit être initialisé que dans le fichier objet qui le contient effectivement, sinon une erreur est produite. Précisons aussi qu’une variable peut être déclarée externe à l’intérieur d’une fonction, bien que ce soit d’un intérêt assez faible.

Déclarés en dehors d’une fonction, les variables et les types (y compris les classes) sont externes par défaut ; les fonctions également. Elles peuvent être déclarées statiques si elles ne sont utilisées que dans le fichier courant :

static void fonc(void){ ...

Dans ce cas, il est possible à plusieurs fichiers objets d’avoir une fonction nommée fonc sans entraîner de conflit, même si les fonctions sont différentes. En fait, l’éditeur de liens ne connaîtra pas le nom de ces fonctions statiques, qui n’est utilisé que par le compilateur et effacé en fin de fichier. La déclaration statique est donc utile pour des fonctions, des variables et des types qui n’ont pas à être utilisés ailleurs, car elle facilite le travail du compilateur et de l’éditeur de liens. Noter aussi qu’une fonction en ligne est inconnue de l’éditeur de liens (elle est toujours statique).

Les constantes sont statiques par défaut ; de la sorte, deux fichiers objets peuvent utiliser chacun leur version d’une constante sans problèmes. Cela permet aussi d’écrire une constante dans un fichier en-tête et d’inclure ce fichier dans plusieurs sources. Une constante peut être déclarée externe, si l’on souhaite l’initialiser ailleurs. Précisons toutefois que les tableaux constants (y compris les chaînes de caractères) ainsi que les classes et structures constantes sont, eux, externes par défaut (afin d’éviter une duplication de leur contenu dans les différents fichiers objets).

Les déclarations de types sont externes par défaut. On peut cependant les répéter dans plusieurs fichiers objets, à condition que ce soit de manière identique (en pratique en passant par un fichier en-tête) ; c’est ce que nous avons fait avec les types fraction et matrice_fra dans notre exemple.

D’une façon générale, on évitera de placer dans un fichier en-tête une définition de fonction (sauf en ligne), de variables (mais une déclaration externe est possible) et de tableaux, classes ou structures constants.

Précédent Précédent Sommaire Sommaire Suivant Suivant