462 Stimmen

Was ist eine externe und eine interne Verknüpfung?

Ich möchte die externe Verknüpfung und die interne Verknüpfung und deren Unterschied verstehen.

Ich möchte auch die Bedeutung von

const Variablen sind standardmäßig intern verknüpft, es sei denn, sie sind anders als extern .

400voto

dudewat Punkte 3554

Wenn Sie eine Implementierungsdatei schreiben ( .cpp , .cxx usw.) erzeugt Ihr Compiler eine Übersetzungseinheit . Dies ist die Quelldatei Ihrer Implementierung plus alle Kopfzeilen, die Sie #include d darin.

Interne Verknüpfung bezieht sich nur auf alles im Rahmen einer Übersetzungseinheit .

Externe Verknüpfung bezieht sich auf Dinge, die außerhalb einer bestimmten Übersetzungseinheit existieren. Mit anderen Worten, zugänglich über das gesamte Programm die die Kombination aller Übersetzungseinheiten (oder Objektdateien) ist.

371voto

Motti Punkte 104854

Als dudewat sagte extern Verknüpfung bedeutet, dass das Symbol (Funktion oder globale Variable) im gesamten Programm zugänglich ist und intern Verknüpfung bedeutet, dass sie nur in einem der folgenden Bereiche zugänglich ist Übersetzungseinheit .

Sie können die Verknüpfung eines Symbols explizit steuern, indem Sie die extern y static Schlüsselwörter. Wenn die Verknüpfung nicht angegeben wird, ist die Standardverknüpfung extern (externe Verknüpfung) für nicht const Symbole und static (interne Verknüpfung) für const Symbole.

// In namespace scope 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 f(); // extern by default
static int sf(); // explicitly static 

Beachten Sie, dass anstelle der Verwendung von static (interne Verknüpfung), ist es besser, die anonyme Namensräume in die Sie auch Folgendes eingeben können class es. Sie erlauben zwar extern Verknüpfung sind anonyme Namensräume für andere Übersetzungseinheiten unerreichbar, so dass die Verknüpfung effektiv static .

namespace {
  int i; // extern by default but unreachable from other translation units
  class C; // extern by default but unreachable from other translation units
}

143voto

Rajendra Uppal Punkte 17720
  • Eine globale Variable hat Außenanbindung standardmäßig. Sein Geltungsbereich kann auf andere Dateien als die, die es enthalten, ausgedehnt werden, indem man einen passenden extern Erklärung in der anderen Datei.
  • Der Geltungsbereich einer globalen Variablen kann auf die Datei beschränkt werden, die ihre Deklaration enthält, indem der Deklaration das Schlüsselwort static . Solche Variablen werden als interne Verknüpfung .

Betrachten Sie folgendes Beispiel:

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  1. Die Signatur der Funktion f erklärt f als eine Funktion mit Außenanbindung (Voreinstellung). Seine Definition muss später in dieser Datei oder in einer anderen Übersetzungseinheit angegeben werden (siehe unten).
  2. max ist als ganzzahlige Konstante definiert. Die Standardverknüpfung für Konstanten ist intern . Seine Verknüpfung wird mit dem Schlüsselwort auf extern geändert extern . Jetzt also max können in anderen Dateien aufgerufen werden.
  3. n ist als ganzzahlige Variable definiert. Die Standardverknüpfung für Variablen, die außerhalb von Funktionskörpern definiert sind, ist extern .

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 wird erklärt, dass Außenanbindung . Eine passende Definition für max (mit externer Verlinkung) muss in irgendeiner Datei erscheinen. (Wie in 1.cpp)
  2. n wird erklärt, dass Außenanbindung .
  3. z es definiert als globale Variable mit interne Verknüpfung .
  4. Die Definition von nCall gibt an. nCall eine Variable zu sein, die ihren Wert über Funktionsaufrufe hinweg beibehält f() . Im Gegensatz zu lokalen Variablen mit der Standard-Autospeicherklasse, nCall wird nur einmal beim Start des Programms initialisiert und nicht bei jedem Aufruf von f() . Der Speicherklassenspezifizierer static betrifft die Lebensdauer der lokalen Variablen und nicht ihren Geltungsbereich.

NB: Das Schlüsselwort static spielt eine doppelte Rolle. Wenn sie in den Definitionen globaler Variablen verwendet wird, gibt sie an interne Verknüpfung . Wenn es in den Definitionen der lokalen Variablen verwendet wird, gibt es an, dass die Lebensdauer der Variablen die Dauer des Programms und nicht die Dauer der Funktion sein wird.

Ich hoffe, das hilft!

32voto

Libin Jose Punkte 335

In Bezug auf "C" (weil das Schlüsselwort "static" in "C" und "C++" unterschiedliche Bedeutung hat)

Lassen Sie uns über verschiedene Bereiche in 'C' sprechen

UMFANG: Es geht darum, wie lange ich etwas sehen kann und wie weit.

  1. Lokale Variable: Der Anwendungsbereich liegt nur innerhalb einer Funktion. Sie befindet sich im STACK-Bereich des RAM. Das bedeutet, dass jedes Mal, wenn eine Funktion aufgerufen wird, alle Variablen die Teil dieser Funktion sind, einschließlich der Funktionsargumente neu erstellt und zerstört werden, sobald die Kontrolle aus der Funktion herausgeht. Funktion geht. (Weil der Stack jedes Mal, wenn die Funktion zurückkehrt, geleert wird)

  2. Statische Variable: Der Anwendungsbereich dieser Variable ist eine Datei. Sie ist an jeder Stelle der Datei zugänglich.
    in dem sie erklärt wird. Er befindet sich im DATA-Segment des RAM. Da kann nur innerhalb einer Datei und damit INTERNAL linkage darauf zugegriffen werden. Jede
    andere Dateien können diese Variable nicht sehen. In der Tat ist das Schlüsselwort STATIC die einzige Möglichkeit, eine bestimmte Ebene von Daten oder Funktionen einzuführen
    Versteckt in 'C'

  3. Globale Variable: Sie gilt für eine gesamte Anwendung. Sie ist zugänglich von jedem der Anwendung zugänglich. Globale Variablen befinden sich auch im DATA-Segment Da auf sie von überall in der Anwendung zugegriffen werden kann und daher EXTERNE Verknüpfung

Standardmäßig sind alle Funktionen global. Für den Fall, dass Sie einige Funktionen in einer Datei von außen verstecken wollen, können Sie das statische Schlüsselwort an die Funktion anhängen :-)

23voto

FrankHB Punkte 1919

Bevor wir uns mit der Frage befassen, ist es besser, den Begriff zu kennen Übersetzungseinheit , Programm und einige Grundkonzepte von C++ (eigentlich ist die Verknüpfung eine davon im Allgemeinen) genau. Sie müssen auch wissen, was ein Umfang .

Ich werde einige wichtige Punkte hervorheben, vor allem diejenigen, die in den vorherigen Antworten fehlten.

Linkage ist eine Eigenschaft einer Name die durch eine Erklärung . Verschiedene Namen können dasselbe bezeichnen Unternehmen (typischerweise ein Objekt oder eine Funktion). Wenn man also über Verknüpfung einer Entität ist in der Regel unsinnig, es sei denn, man ist sich sicher, dass die Entität nur durch den eindeutigen Namen aus bestimmten Deklarationen (in der Regel eine Deklaration) referenziert wird.

Hinweis an Objekt ist eine Entität, aber eine variabel ist nicht. Wenn von der Verknüpfung einer Variablen die Rede ist, geht es eigentlich um den Namen der bezeichneten Entität (die durch eine bestimmte Erklärung eingeführt wird). Die Verknüpfung des Namens erfolgt in einer der drei Varianten: keine Verknüpfung, interne Verknüpfung oder externe Verknüpfung.

Verschiedene Übersetzungseinheiten können dieselbe Deklaration durch Einbindung von Headern/Quelldateien (ja, das ist der Wortlaut der Norm) verwenden. Sie können also denselben Namen in verschiedenen Übersetzungseinheiten verwenden. Wenn der deklarierte Name eine externe Verknüpfung hat, wird auch die Identität der Entität, auf die der Name verweist, geteilt. Wenn der deklarierte Name eine interne Verknüpfung hat, bezeichnet derselbe Name in verschiedenen Übersetzungseinheiten verschiedene Entitäten, aber Sie können die Entität in verschiedenen Bereichen derselben Übersetzungseinheit referenzieren. Wenn der Name keine Verknüpfung hat, können Sie die Entität nicht aus anderen Bereichen referenzieren.

(Ups... Ich fand, was ich getippt habe, war irgendwie nur wiederholend die Standardformulierung ...)

Es gibt auch einige andere verwirrende Punkte, die nicht in der Sprachspezifikation enthalten sind.

  1. Sichtbarkeit (eines Namens). Es ist auch eine Eigenschaft des deklarierten Namens, aber mit einer anderen Bedeutung als Linkage .
  2. Sichtbarkeit (einer Nebenwirkung) . Dies hat nichts mit diesem Thema zu tun.
  3. Sichtbarkeit (eines Symbols). Dieser Begriff kann sein von tatsächlichen Implementierungen verwendet . In solchen Implementierungen ist ein Symbol mit spezifischer Sichtbarkeit im Objektcode (Binärcode) in der Regel das Ziel, das von der Entitätsdefinition abgebildet wird, deren Namen die gleiche spezifische Verknüpfung im Quellcode (C++) haben. Dies ist jedoch normalerweise nicht eins-zu-eins garantiert. Zum Beispiel kann ein Symbol in einem dynamischen Bibliotheks-Image nur in diesem Image intern vom Quellcode aus freigegeben werden (mit einigen Erweiterungen, typischerweise, __attribute__ ou __declspec ) oder Compiler-Optionen, und das Bild ist nicht das ganze Programm oder die Objektdatei, die aus einer Übersetzungseinheit übersetzt wird, daher kann kein Standardkonzept es genau beschreiben. Da Symbol in C++ kein normativer Begriff ist, handelt es sich nur um ein Implementierungsdetail, auch wenn die entsprechenden Erweiterungen der Dialekte weithin übernommen wurden.
  4. Zugänglichkeit. In C++ geht es dabei in der Regel um Eigenschaft von Klassenmitgliedern oder Basisklassen was wiederum ein anderes Konzept ist, das nichts mit dem Thema zu tun hat.
  5. Global. In C++ bezieht sich "global" auf etwas aus dem globalen Namespace oder dem globalen Namespace-Bereich. Letzteres entspricht in etwa Umfang der Datei in der Sprache C. Sowohl in C als auch in C++ hat die Verknüpfung nichts mit dem Geltungsbereich zu tun, obwohl der Geltungsbereich (wie die Verknüpfung) auch eng mit einem Bezeichner (in C) oder einem Namen (in C++) verbunden ist, der durch eine Deklaration eingeführt wird.

Le site Verknüpfungsregel des Namespace-Bereichs const variabel ist etwas Besonderes (und vor allem anders als die const Objekt, das in der Sprache C, die auch das Konzept der Verknüpfung von Bezeichnern hat, im Dateisystem deklariert ist). Da ODR wird von C++ erzwungen, ist es wichtig, dass im gesamten Programm nicht mehr als eine Definition derselben Variablen oder Funktion vorkommt, außer bei inline Funktionen . Wenn es keine solche besondere Regel gibt, die const eine einfachste Erklärung von const Variable mit Initialisierungen (z. B. = xxx ) in einem Header oder einer Quelldatei (oft eine "Header-Datei"), die von mehreren Übersetzungseinheiten (oder von einer Übersetzungseinheit mehr als einmal, wenn auch selten) in ein Programm eingebunden wird, verstößt gegen ODR, das die Verwendung von const Variable als Ersatz für einige objektähnliche Makros unmöglich.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X