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éeextern
.
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 #include
d.
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).
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 class
es. 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 { };
}
Considérons l'exemple suivant:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
#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;
}
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!
Parlons de différentes portées en 'C'
PORTÉE: C'est essentiellement combien de temps puis-je voir quelque chose et à quelle distance.
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)
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'
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. :-)
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.
__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.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.
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
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:
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
Fondamentalement
extern linkage
est visible dans tous les fichiersinternal 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
external linkage
const
est internal linkage
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++/
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.