Rappelons tout d'abord quel est le rôle d'un éditeur de liens. Un programme compilé (module objet) peut faire référence à des noms d'objets (fonctions ou variables) dont la définition n'est pas présente dans le programme (c'est ce qu'on appelle des références externes). Ce module peut lui-même donner accès à des fonctions ou variables qu'il a défini. On peut ainsi construire des bibliothèques de programmes. Un module objet (ou une bibliothèque) aura un index (``name list'') qui associe des noms à des adresses (de fonctions ou de variables) de ce module. Pour obtenir un exécutable, il faut que toutes les références externes soient résolues, c'est-à-dire que toutes les références externes soient associées à des adresses. C'est l'éditeur de liens qui se chargera de résoudre les références externes. Un éditeur de liens, comme l'éditeur standard d'UNIX, ne connaît que les noms, il n'a aucune connaissance du typage.
Du point de vue de l'édition de liens, un nom peut être
visible ou invisible.
Il y a donc deux sortes de liens : le lien externe (accessible à l'éditeur de
lien) et lien interne (accessible uniquement localement à l'intérieur d'un
fichier). Pour un objet, avoir un lien externe signifie qu'il est réellement
accessible et que l'allocation de cet objet sera
unique et faite à la compilation ; pour un type (où il n'y aura donc pas
d'allocation) un lien externe signifie plutôt que le nom correspond à la même
classe pour tous les modules.
Par défaut, un nom global (portée du fichier), aura un lien externe, et un nom local un lien interne. Le mot clé static et le mot clé extern permettent de modifier cette règle. Un objet ou une classe déclarée static, aura un lien interne, alors qu'une déclaration extern spécifie un lien externe.
fichier f: int a; // définition de a lien externe static int b ; // définition b lien interne class A{ int f(); // lien externe // ... } x; // nom global lien externe extern c; // déclaration de b (lien externe) fichier g: static int a; // lien interne int c; // définition et lien externe static void f(int i){ // lien interne extern int a; // lien externe ... }
Alors que les classes ont un lien externe et ne peuvent être déclarées static, les énumérateurs, les patrons et les typedef n'ont pas de lien externe.
En résumé, pour le C++, comme le C, un nom global aura en général un lien externe contrairement à un nom local.