Ich möchte die externe Verknüpfung und die interne Verknüpfung und ihren Unterschied verstehen.
Ich möchte auch die Bedeutung von kennen
const
-Variablen werden standardmäßig intern verknüpft, sofern nicht anders alsextern
deklariert.
Wenn Sie eine Implementierungsdatei schreiben (.cpp
, .cxx
usw.), generiert Ihr Compiler eine Übersetzungseinheit . Dies ist die Objektdatei aus Ihrer Implementierungsdatei sowie alle Header, die Sie #include
d darin enthalten.
Interne Verknüpfung bezieht sich nur auf alles im Umfang einer Übersetzungseinheit .
Externe Verknüpfung bezieht sich auf Dinge, die über eine bestimmte Übersetzungseinheit hinaus existieren. Mit anderen Worten, durch das gesamte Programm zugänglich , das ist die Kombination aller Übersetzungseinheiten (oder Objektdateien).
Wie dudewat sagteexternal - Verknüpfung bedeutet, dass das Symbol (Funktion oder globale Variable) im gesamten Programm verfügbar ist, und interne - Verknüpfung bedeutet, dass es nur in einer Übersetzungseinheit verfügbar ist.
Sie können die Verknüpfung eines Symbols mithilfe der Schlüsselwörter extern
und static
explizit steuern. Wenn die Verknüpfung nicht angegeben ist, lautet die Standardverbindung extern
für Symbole, die keine const
-Symbole sind, und static
(intern) für const
-Symbole.
// 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
Beachten Sie, dass Sie anstelle von static
für die interne Verknüpfung besser anonyme Namespaces verwenden, in die Sie auch class
es einfügen können. Die Verknüpfung für anonyme Namespaces wurde zwischen C++ 98 und C++ 11 geändert. Die Hauptsache ist jedoch, dass sie von anderen Übersetzungseinheiten nicht erreichbar sind.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
Betrachten Sie folgendes Beispiel:
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: Das Schlüsselwort static spielt eine doppelte Rolle. Bei Verwendung in den Definitionen globaler Variablen gibt es internal linkage an. Bei Verwendung in den Definitionen der lokalen Variablen wird angegeben, dass die Lebensdauer der Variablen die Dauer des Programms und nicht die Dauer der Funktion ist.
Hoffentlich hilft das!
Reden wir über verschiedene Bereiche in 'C'
UMFANG: Es ist grundsätzlich, wie lange ich etwas sehen kann und wie weit.
Lokale Variable: Der Gültigkeitsbereich befindet sich nur innerhalb einer Funktion. Es befindet sich im STACK-Bereich von RAM . Dies bedeutet, dass jedes Mal, wenn eine Funktion alle Variablen aufgerufen wird das sind der Teil dieser Funktion, einschließlich der Funktionsargumente sind frisch erstellt und zerstört, sobald die Kontrolle aus der Funktion. (Da der Stack jedes Mal geleert wird, wenn die Funktion zurückkehrt)
Statische Variable: Der Gültigkeitsbereich bezieht sich auf eine Datei. Es ist überall in der Datei zugänglich
in dem es erklärt wird. Es befindet sich im DATA-Segment des RAM. Schon seit Darauf kann nur innerhalb einer Datei und somit auf eine INTERNE Verknüpfung zugegriffen werden. Irgendein
Andere Dateien können diese Variable nicht sehen. In der Tat ist das Schlüsselwort STATIC das Nur so können wir ein gewisses Maß an Daten oder Funktionen einführen
versteckt sich in 'C'
Globale Variable: Der Geltungsbereich gilt für eine gesamte Anwendung. Es ist von jedem Ort aus zugänglich wo des Antrags. Globale Variablen befinden sich auch im DATA-Segment Da kann überall auf die Anwendung zugegriffen werden und somit EXTERNE Verknüpfung
Standardmäßig sind alle Funktionen global. Falls Sie einige Funktionen in einer Datei von außen verbergen müssen, können Sie das statische Schlüsselwort Der Funktion voranstellen. :-)
Bevor Sie über die Frage sprechen, ist es besser, den Begriff translation unit , program und einige Grundbegriffe von C++ zu kennen ( Tatsächlich ist die Verknüpfung eine von ihnen im Allgemeinen). Sie müssen auch wissen, was ein scope ist.
Ich werde einige wichtige Punkte hervorheben, insbes. die in vorherigen Antworten fehlten.
Linkage ist eine Eigenschaft eines name, die durch eine Deklaration eingeführt wird. Verschiedene Namen können dieselbe entity (normalerweise ein Objekt oder eine Funktion) bezeichnen. Über linkage einer Entität zu sprechen, ist in der Regel Unsinn, es sei denn, Sie sind sicher, dass die Entität nur durch den eindeutigen Namen von bestimmten Deklarationen (normalerweise einer Deklaration) referenziert wird.
Beachten Sie, dass ein Objekt eine Entität ist, eine Variable jedoch nicht. Bei der Verknüpfung einer Variablen ist eigentlich der Name der bezeichneten Entität (die durch eine bestimmte Deklaration eingeführt wird) betroffen. Die Verknüpfung des Namens erfolgt in einer der drei Kategorien: Keine Verknüpfung, interne Verknüpfung oder externe Verknüpfung.
Unterschiedliche Übersetzungseinheiten können dieselbe Deklaration nach Header-/Quelldatei (ja, es ist der Wortlaut des Standards) enthalten. Sie können also in verschiedenen Übersetzungseinheiten auf denselben Namen verweisen. Wenn der angegebene Name über eine externe Verknüpfung verfügt, wird auch die Identität der Entität, auf die der Name verweist, gemeinsam genutzt. Wenn der deklarierte Name über eine interne Verknüpfung verfügt, bezeichnet derselbe Name in verschiedenen Übersetzungseinheiten verschiedene Entitäten. Sie können jedoch auf die Entität in verschiedenen Bereichen derselben Translationseinheit verweisen. Wenn der Name keine Verknüpfung hat, können Sie die Entität einfach nicht aus anderen Bereichen referenzieren.
(Hoppla ... Ich habe festgestellt, dass das, was ich geschrieben habe, nur die Wiederholung von dem Standardwortlaut ...) ist.
Es gibt auch einige andere verwirrende Punkte, die nicht in der Sprachspezifikation enthalten sind.
__attribute__
oder __declspec
) oder Compileroptionen gemeinsam genutzt werden, und das Abbild ist nicht das gesamte Programm oder die Objektdatei übersetzt aus einer Übersetzungseinheit, daher kann kein Standardkonzept es genau beschreiben. Da das Symbol in C++ kein normativer Begriff ist, handelt es sich nur um ein Implementierungsdetail, auch wenn die zugehörigen Erweiterungen von Dialekten möglicherweise weit verbreitet sind.Die Verknüpfungsregel des Namespace-Bereichs const
variable ist etwas Besonderes (und unterscheidet sich insbesondere von dem const
-Objekt, das im Dateibereich in C-Sprache deklariert ist und auch das Konzept der Verknüpfung von Bezeichnern hat). Da ODR von C++ erzwungen wird, ist es ist wichtig, dass nicht mehr als eine Definition derselben Variablen oder Funktion im gesamten Programm verwendet wird, mit Ausnahme von inline
-Funktionen . Wenn es keine solche Sonderregel für const
gibt, wird eine einfachste Deklaration der Variable const
mit Initialisierern (z. B. = xxx
) in einem Header oder einer Quelldatei (häufig eine "Headerdatei") in mehreren Übersetzungseinheiten (oder in einer weiteren Übersetzungseinheit) enthalten mehr als einmal, wenn auch selten) in einem Programm verstößt gegen ODR, wodurch die Verwendung der Variable const
als Ersatz für objektartige Makros unmöglich ist.
Ich denke, Interne und externe Verknüpfung in C++ gibt eine klare und knappe Erklärung:
Eine Übersetzungseinheit bezieht sich auf eine Implementierungsdatei (.c/.cpp) und alle Header-Dateien (.h/.hpp) enthalten. Wenn ein Objekt oder eine Funktion in eine solche Übersetzungseinheit hat eine interne Verknüpfung, dann die spezifische Das Symbol ist nur für den Linker in dieser Übersetzungseinheit sichtbar. Ob Wenn ein Objekt oder eine Funktion eine externe Verknüpfung hat, kann der Linker sie auch sehen bei der Verarbeitung anderer Übersetzungseinheiten. Das statische Schlüsselwort, wenn es verwendet wird Erzwingt im globalen Namespace die interne Verknüpfung eines Symbols. Das Ein externes Schlüsselwort führt zu einem Symbol mit externer Verknüpfung.
Der Compiler setzt die Verknüpfung von Symbolen standardmäßig wie folgt:
Nicht-konstante globale Variablen verfügen standardmäßig über eine externe Verknüpfung
Globale Const-Variablen verfügen standardmäßig über eine interne Verknüpfung
Funktionen haben standardmäßig eine externe Verknüpfung
Die Verknüpfung bestimmt, ob Bezeichner mit identischen Namen sich auf dasselbe Objekt, dieselbe Funktion oder eine andere Entität beziehen, selbst wenn diese Bezeichner in unterschiedlichen Übersetzungseinheiten erscheinen. Die Verknüpfung eines Bezeichners hängt davon ab, wie er deklariert wurde .. Es gibt drei Arten von Verknüpfungen:
Nur C++: Sie können auch eine Verknüpfung zwischen C++ - und Nicht-C++ - Codefragmenten haben, die als language linkage bezeichnet wird.
Quelle: IBM-Programmverknüpfung
Grundsätzlich gilt
extern linkage
-Variable ist in allen Dateien sichtbarinternal linkage
-Variable ist in einer einzelnen Datei sichtbar.Explain: const-Variablen werden standardmäßig intern verknüpft, sofern nicht anders als extern deklariert.
external linkage
.const
globale Variable ist internal linkage
extern const
globale Variable external linkage
Ein ziemlich gutes Material über die Verknüpfung in C++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
In C++
Jede Variable im Dateibereich, die nicht in einer Klasse oder Funktion verschachtelt ist, ist in allen Übersetzungseinheiten eines Programms sichtbar. Dies wird als external linkage bezeichnet, da der Name zum Linker für den Linker überall außerhalb der Übersetzungseinheit sichtbar ist.
Globale Variablen und gewöhnliche Funktionen haben eine externe Verknüpfung.
Statisch Der Objekt- oder Funktionsname im Dateibereich ist lokal für die Übersetzungseinheit. Das ist Als Internal Linkage bezeichnet.
Verknüpfung bezieht sich nur auf Elemente, die zum Zeitpunkt des Verbindens/Ladens Adressen haben. Klassendeklarationen und lokale Variablen haben daher keine Verknüpfung.