web-dev-qa-db-fra.com

Qu'est-ce qu'un lien externe et un lien interne?

Je veux comprendre le lien externe et le lien interne et leur différence. 

Je veux aussi connaître le sens de

Les variables const sont liées de manière interne par défaut, sauf indication contraire déclarée extern.

297
rkb

Lorsque vous écrivez un fichier d'implémentation (.cpp, .cxx, etc.), votre compilateur génère un unité de traduction. Il s'agit du fichier objet de votre fichier d'implémentation, ainsi que de tous les en-têtes avec lesquels vous #included. 

Lien interne fait référence à tout ce qui se trouve dans le cadre d'une unité de traduction.

Lien externe fait référence à des éléments extérieurs à une unité de traduction particulière. En d’autres termes, accessible par l’ensemble du programme, qui est la combinaison de toutes les unités de traduction (ou fichiers objets).

239
dudewat

Comme dudewat a ditexternal signifie que le symbole (fonction ou variable globale) est accessible dans tout votre programme et que internal signifie qu'il est uniquement accessible dans un unité de traduction

Vous pouvez contrôler explicitement le lien d'un symbole en utilisant les mots clés extern et static. Si le lien n'est pas spécifié, le lien par défaut est extern pour les symboles non -const et static (interne) pour les symboles const.

// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static

// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static 

Notez qu'au lieu d'utiliser static pour la liaison interne, il est préférable d'utiliser les espaces de noms anonymes dans lesquels vous pouvez également insérer classes. La liaison pour les espaces de noms anonymes a changé entre C++ 98 et C++ 11, mais l’essentiel est qu’ils soient inaccessibles à partir d’autres unités de traduction.

namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}
259
Motti
  • Une variable globale a external linkage par défaut. Son étendue peut être étendue à des fichiers autres que le contenant en donnant une déclaration correspondante extern dans l'autre fichier.
  • La portée d'une variable globale peut être limitée au fichier contenant sa déclaration en préfixant celle-ci avec le mot clé static. On dit que ces variables ont internal linkage.

Considérons l'exemple suivant:

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  1. La signature de la fonction f déclare f en tant que fonction avec external linkage (par défaut). Sa définition doit être fournie plus tard dans ce fichier ou dans une autre unité de traduction (donnée ci-dessous).
  2. max est défini comme une constante entière. Le lien par défaut pour les constantes est internal. Son lien est changé en externe avec le mot clé extern. Alors maintenant, max peut être consulté dans d'autres fichiers. 
  3. n est défini comme une variable entière. Le lien par défaut pour les variables définies en dehors du corps des fonctions est external.

2.cpp

#include <iostream>
using namespace std;

extern const int max;
extern int n;
static float z = 0.0;

void f(int i)
{
    static int nCall = 0;
    int a;
    //...
    nCall++;
    n++;
    //...
    a = max * z;
    //...
    cout << "f() called " << nCall << " times." << endl;
}
  1. max est déclaré avoir external linkage. Une définition correspondante pour max (avec une liaison externe) doit apparaître dans un fichier. (Comme dans 1.cpp)
  2. n est déclaré avoir external linkage.
  3. z est défini en tant que variable globale avec lien interne.
  4. La définition de nCall spécifie que nCall est une variable qui conserve sa valeur lors des appels à la fonction f (). Contrairement aux variables locales avec la classe de stockage automatique par défaut, nCall ne sera initialisé qu'une fois au début du programme et pas une fois pour chaque appel de f (). Le spécificateur de classe de stockage static affecte la durée de vie de la variable locale et non son étendue.

NB: Le mot clé static joue un double rôle. Lorsqu'il est utilisé dans les définitions de variables globales, il spécifie linkage interne. Lorsqu'il est utilisé dans les définitions des variables locales, il spécifie que la durée de vie de la variable sera la durée du programme au lieu de la durée de la fonction.

J'espère que cela pourra aider!

82
Rajendra Uppal

En termes de "C" (car le mot clé statique a une signification différente entre "C" et "C++")

Parlons de différentes portées en 'C'

PORTÉE: C'est essentiellement combien de temps puis-je voir quelque chose et à quelle distance.

  1. Variable locale: l'étendue est uniquement à l'intérieur d'une fonction. Il réside dans la zone STACK de RAM . Ce qui signifie que chaque fois qu'une fonction est appelée toutes les variables qui sont la partie de cette fonction, y compris les arguments de la fonction sont fraîchement créé et sont détruits une fois que le contrôle est sorti de la une fonction. (Parce que la pile est vidée chaque fois que la fonction retourne)

  2. Variable statique: La portée de ceci concerne un fichier. Il est accessible partout dans le fichier.
    dans lequel il est déclaré. Il réside dans le segment DATA de la RAM. Puisque cela ne peut être consulté qu'à l'intérieur d'un fichier et donc d'un lien INTERNE. Tout
    les autres fichiers ne peuvent pas voir cette variable. En fait, le mot clé STATIC est le seul moyen d'introduire un certain niveau de données ou de fonction
    se cacher dans 'C'

  3. Variable globale: la portée de cette opération concerne une application entière. Il est accessible depuis chaque où de l'application. Les variables globales résident également dans le segment DATA Puisqu'il peut être consulté partout dans l'application et donc Liaison EXTERNE

Par défaut, toutes les fonctions sont globales. Si vous avez besoin de masquer certaines fonctions d’un fichier de l’extérieur, vous pouvez préfixer le mot clé statique À la fonction. :-)

25
Libin Jose

Avant de parler de la question, il vaut mieux connaître le terme unité de traduction , programme et quelques concepts de base de C++ (en réalité, le lien est l'un d'entre eux en général) précisément. Vous devrez également savoir ce qui est un scope .

Je soulignerai quelques points clés, en particulier ceux qui manquent dans les réponses précédentes.

Linkage est une propriété d'un name, qui est introduit par un déclaration. Des noms différents peuvent désigner la même entité (généralement un objet ou une fonction). Donc, parler de linkage d'une entité est généralement un non-sens, à moins que vous ne soyez sûr que l'entité ne sera référée que par le nom unique de certaines déclarations spécifiques (généralement une déclaration cependant).

Notez que object est une entité, mais que variable ne l’est pas. En parlant du lien d'une variable, le nom de l'entité notée (qui est introduite par une déclaration spécifique) est concerné. Le lien entre le nom est l'un des trois suivants: pas de lien, lien interne ou lien externe.

Différentes unités de traduction peuvent partager la même déclaration par en-tête/fichier source (oui, il s'agit du libellé de la norme). Vous pouvez donc faire référence au même nom dans différentes unités de traduction. Si le nom déclaré a une liaison externe, l'identité de l'entité référencée par le nom est également partagée. Si le nom déclaré a une liaison interne, le même nom dans différentes unités de traduction indique différentes entités, mais vous pouvez faire référence à l'entité dans différentes portées de la même unité de traduction. Si le nom n'a pas de lien, vous ne pouvez tout simplement pas renvoyer l'entité à partir d'autres portées.

(Oups ... j'ai trouvé que ce que j'ai tapé était un peu en train de répéter le libellé standard ...)

Il existe également d'autres points de confusion qui ne sont pas couverts par la spécification de langue.

  1. Visibilité (d'un nom). C'est aussi une propriété de nom déclaré, mais avec une signification différente de linkage .
  2. Visibilité (d'un effet secondaire) . Ce n'est pas lié à ce sujet.
  3. Visibilité (d'un symbole). Cette notion peut être utilisée par les implémentations réelles . Dans de telles implémentations, un symbole ayant une visibilité spécifique dans un code objet (binaire) est généralement la cible mappée à partir de la définition d'entité dont les noms ont le même lien spécifique dans le code source (C++). Cependant, il n'est généralement pas garanti un à un. Par exemple, un symbole dans une image de bibliothèque dynamique peut être spécifié uniquement partagé en interne dans cette image à partir du code source (impliqué dans certaines extensions, généralement, __attribute__ ou __declspec) ou des options du compilateur, et l'image n'est pas le programme entier ni le fichier objet. traduit d'une unité de traduction, aucun concept standard ne peut donc la décrire avec précision. Puisque symbole n'est pas un terme normatif en C++, il ne s'agit que d'un détail d'implémentation, même si les extensions de dialectes associées ont été largement adoptées.
  4. Accessibilité. En C++, il s'agit généralement de la propriété des membres de la classe ou des classes de base , qui est encore une fois un concept différent, indépendant du sujet.
  5. Global. En C++, "global" fait référence à quelque chose d'espace de noms global ou à sa portée. Ce dernier est à peu près équivalent à file scope en langage C. Tant en C qu'en C++, le lien n'a rien à voir avec scope, bien que scope (comme lien) soit également étroitement lié à un identifiant (en C) ou à un nom (en C++) introduit par une déclaration.

La règle de liaison de la variable const de la portée de l'espace de noms est quelque chose de spécial (et particulièrement différent de l'objet const déclaré dans la portée du fichier en langage C, qui utilise également le concept de liaison d'identificateurs). Puisque ODR est appliqué par C++, il est important de ne pas conserver plus d'une définition de la même variable ou de la même fonction dans l'ensemble du programme, à l'exception de inline fonctions . S'il n'existe pas de telle règle spéciale de const, une déclaration la plus simple de la variable const avec des initialiseurs (par exemple, = xxx) dans un en-tête ou un fichier source (souvent un "fichier d'en-tête") incluse dans plusieurs unités de traduction (ou incluse dans une unité de traduction plus qu’une fois, bien que rarement) dans un programme violera l’ODR, ce qui rend impossible l’utilisation de la variable const en remplacement de certaines macros de type objet.

10
FrankHB

Je pense que les liens internes et externes en C++ donnent une explication claire et concise: 

Une unité de traduction fait référence à un fichier d'implémentation (.c/.cpp) et à tous les fichiers en-tête (.h/.hpp) les fichiers qu’il inclut. Si un objet ou une fonction à l'intérieur une telle unité de traduction a un lien interne, alors ce spécifique Le symbole n'est visible que pour l'éditeur de liens au sein de cette unité de traduction. Si un objet ou une fonction a un lien externe, l'éditeur de liens peut également le voir lors du traitement d'autres unités de traduction. Le mot clé static, lorsqu'il est utilisé dans l’espace de noms global, force un symbole à avoir un lien interne. Le Le mot-clé extern donne à un symbole un lien externe.

Le compilateur utilise par défaut le couplage de symboles tel que: 

Les variables globales non constantes ont un lien externe par défaut
Les variables globales Const ont un lien interne par défaut
Les fonctions ont un lien externe par défaut

5
Nan Xiao

La liaison détermine si les identificateurs portant des noms identiques font référence au même objet, à la même fonction ou à une autre entité, même si ces identificateurs apparaissent dans des unités de traduction différentes. Le couplage d'un identifiant dépend de la façon dont il a été déclaré ... Il existe trois types de couplage:

  1. Lien interne: les identificateurs ne peuvent être vus que dans une unité de traduction.
  2. Lien externe: les identificateurs peuvent être vus (et référencés) dans d'autres unités de traduction.
  3. Pas de lien: les identificateurs ne peuvent être vus que dans la portée dans laquelle ils sont définis . Le lien n'affecte pas la portée

C++ uniquement: Vous pouvez également établir une liaison entre des fragments de code C++ et non C++, appelée language linkage.

Source: Liaison de programme IBM

4
arun pal

Fondamentalement

  • La variable extern linkage est visible dans tous les fichiers
  • La variable internal linkage est visible dans un seul fichier.

Explain: les variables const sont intrinsèquement liées par défaut, sauf indication contraire en tant qu'extern

  1. par défaut, la variable globale est external linkage
  2. mais la variable globale const est internal linkage
  3. extra, extern const la variable globale est external linkage

Un très bon matériel sur les liens en C++

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/

3
Color

En C++  

Toute variable de la portée du fichier et non imbriquée dans une classe ou une fonction est visible dans toutes les unités de traduction d'un programme. Ceci s'appelle external linkage parce qu'au moment de la liaison, le nom est visible par l'éditeur de liens partout, à l'extérieur de cette unité de traduction. 

Les variables globales et les fonctions ordinaires ont un lien externe.

Static Le nom d'objet ou de fonction au niveau du fichier est local pour l'unité de traduction. C’est-à-dire Appelé Lien interne

La liaison fait uniquement référence aux éléments ayant des adresses au moment du lien/du chargement; ainsi, les déclarations de classe et les variables locales n'ont pas de lien.

0
Saurabh Raoot