La modification imperceptible des variables globales est une des principales difficultés rencontrées dans la maintenance des programme. C’est pourquoi la première recommandation est de ne pas utiliser de variables globales. Dans la construction des types de données abstrait, la systèmatisation de cette idée conduit à n’admettre l’accès aux données qu’au moyen de fonctions associées au types de données.

Domaine de visibilité des variables et fonctions

Règles des espaces de visibilité :
  • Un programme C est composé de nombreux éléments qui sont des variables ou des fonctions. Afin d’éviter les conflits de noms, le langage permet de restreindre la visibilité de certains objets qui n’ont aucune raison d’être globaux (comme les indices de boucles).
  • L’espace de visibilité d’une variable ou d’une fonction correspond à la partie de source pour laquelle elle est définie (connue).
  • De manière générale une variable est définie depuis sa déclaration jusqu’à l’accolade fermante qui la suit ou jusqu’à la fin du module si elle n’est pas à l’intérieur d’une paire d’accolade.
  • Une variable définie dans une fonction n’est donc visible que dans cette fonction. Une variable déclarée hors de toute fonction est visible jusqu’à la fin de son module. Elle peut, dans ce cas, être rendue visible depuis les autres modules de l’application (c’est à dire exportée) ou rester privée au module qui la déclare.
  • Une fonction est visible dans l’ensemble du fichier qui la contient.
  • Elle peut être rendue visible des autres modules ou conservée privée. Exemple :
    /* Hors du module,
     * importee */
    extern int V1 ; 
    
    /* Globale au module,
     * exportee vers les autres */
    int V2 ;
    
    /* Globale au module,
     * non visible depuis les autres */
    static int V3 ;
    
    /* V1, V2, V3, F1 et F2
     * sont visibles */
    
    /* Fonction non exportee */
    static int F1 ()
    {
        int V4 ; /* Locale a F1 */
        int V2 ;
        /* La variable V2 globale
         * est cachee par celle-ci 
         * V1, V2, V3, V4, F1 et F2
         * sont visibles 
         * La version globale de V2
         * est inaccessible */
    }
    
    /* V1, V2, V3, F1 et F2
     * sont visibles */
    int V5 ;
    
    /* V1, V2, V3, V5, F1 et F2
     * sont visibles */
    
    int F2 () /* Fonction exportee */
    {
        /* Variable locale permanente */
         static V6 ;
        /* V1, V2, V3, V5, V6, F1 et F2
         * sont visibles */
    }
    
    /* V1, V2, V3, V5, F1 et F2
     * sont visibles */
    
    /* V2, V5 et F2
     * sont visibles depuis d'autres modules */
    
    
  • Si l’on veut qu’une variable déclarée dans un autre fichier soit visible dans le module courant, elle doit être déclarée externe dans celui-ci. A contrario, une fonction appelée dans un module est supposée externe. Si le compilateur la rencontre dans ce même module, il supprime son importation. En d’autres termes, on peut appeler toutes les fonctions de tous les modules sans avoir à annoncer explicitement qu’elles sont externes.
La dernière étape de construction de l’application consiste à collecter l’ensemble de ses constituants pour créer l’exécutable. C’est l’édition des liens. L’application ne peut être correctement construite que si chacun des objets importé par chacun des modules est publié par exactement un autre module. C’est à dire que tous les objets que les modules importent, d’autres les exportent.