Meine Frage ist, wann eine Funktion mit dem extern
Schlüsselwort in C referenziert werden soll .
Ich sehe nicht ein, wann dies in der Praxis angewendet werden sollte. Während ich ein Programm schreibe, werden alle von mir verwendeten Funktionen über die von mir enthaltenen Header-Dateien verfügbar gemacht. Warum sollte es also nützlich sein, extern
auf etwas zuzugreifen, das nicht in der Header-Datei verfügbar war?
Ich könnte darüber nachdenken, wie es extern
falsch funktioniert, und wenn ja, korrigieren Sie mich bitte.
Bearbeiten: Sollten Sie extern
etwas tun , wenn es sich um die Standarddeklaration ohne das Schlüsselwort in einer Header-Datei handelt?
Antworten:
"
extern
" ändert die Verknüpfung. Mit dem Schlüsselwort wird angenommen, dass die Funktion / Variable an einer anderen Stelle verfügbar ist, und die Auflösung wird auf den Linker verschoben.Es gibt einen Unterschied zwischen "extern" bei Funktionen und bei Variablen: Bei Variablen wird die Variable selbst nicht instanziiert, dh es wird kein Speicher zugewiesen. Dies muss woanders gemacht werden. Daher ist es wichtig, wenn Sie die Variable von einem anderen Ort importieren möchten. Bei Funktionen teilt dies dem Compiler nur mit, dass die Verknüpfung extern ist. Da dies die Standardeinstellung ist (Sie verwenden das Schlüsselwort "static", um anzuzeigen, dass eine Funktion nicht über eine externe Verknüpfung gebunden ist), müssen Sie sie nicht explizit verwenden.
quelle
extern teilt dem Compiler mit, dass diese Daten irgendwo definiert sind und mit dem Linker verbunden werden.
Mit Hilfe der Antworten hier und im Gespräch mit einigen Freunden hier ist das praktische Beispiel für die Verwendung von extern .
Beispiel 1 - um eine Falle zu zeigen:
Wenn myCFile1.o und myCFile2.o verknüpft sind, enthält jede der c-Dateien separate Kopien von errno . Dies ist ein Problem, da in allen verknüpften Dateien dieselbe Fehlernummer verfügbar sein soll.
Beispiel 2 - Das Update.
Wenn nun sowohl myCFile1.o als auch MyCFile2.o durch den Linker verknüpft sind, zeigen beide auf denselben Fehler . Somit wird die Implementierung mit extern gelöst .
quelle
-Wall
und keinen Fehler oder keine Warnung aus-pedantic
. Warum ? und wie ?Es wurde bereits festgestellt, dass das
extern
Schlüsselwort für Funktionen redundant ist.Variablen, die von Kompilierungseinheiten gemeinsam genutzt werden, sollten in einer Header-Datei mit dem Schlüsselwort extern deklariert und dann in einer einzigen Quelldatei ohne das Schlüsselwort extern definiert werden. Die Single-Source-Datei sollte diejenige sein, die den Namen der Header-Datei teilt.
quelle
Viele Jahre später entdecke ich diese Frage. Nachdem ich jede Antwort und jeden Kommentar gelesen hatte, dachte ich, ich könnte ein paar Details klären ... Dies könnte für Leute nützlich sein, die über die Google-Suche hierher kommen.
Die Frage bezieht sich speziell auf die Verwendung von "extern" -Funktionen, daher werde ich die Verwendung von "extern" mit globalen Variablen ignorieren.
Definieren wir 3 Funktionsprototypen:
Die Header-Datei kann vom Hauptquellcode wie folgt verwendet werden:
Um zu kompilieren und zu verknüpfen, müssen wir "function_2" in derselben Quellcodedatei definieren, in der wir diese Funktion aufrufen. Die beiden anderen Funktionen können in unterschiedlichem Quellcode " .C" definiert sein oder sich in einer beliebigen Binärdatei ( .OBJ, * .LIB, * .DLL) befinden, für die wir möglicherweise nicht den Quellcode haben.
Fügen wir den Header "my_project.H" erneut in eine andere "* .C" -Datei ein, um den Unterschied besser zu verstehen. Im selben Projekt fügen wir die folgende Datei hinzu:
Wichtige Merkmale zu beachten:
Wenn eine Funktion in einer Header-Datei als "statisch" definiert ist, muss der Compiler / Linker in jedem Modul, das diese Include-Datei verwendet, eine Instanz einer Funktion mit diesem Namen finden.
Eine Funktion, die Teil der C-Bibliothek ist, kann in nur einem Modul ersetzt werden, indem ein Prototyp nur in diesem Modul mit "statisch" neu definiert wird. Ersetzen Sie beispielsweise einen Aufruf von "malloc" und "free", um die Funktion zur Erkennung von Speicherverlusten hinzuzufügen.
Der Bezeichner "extern" wird für Funktionen nicht wirklich benötigt. Wenn "statisch" nicht gefunden wird, wird eine Funktion immer als "extern" angenommen.
"Extern" ist jedoch nicht die Standardeinstellung für Variablen. Normalerweise muss jede Header-Datei, die Variablen definiert, die in vielen Modulen sichtbar sein sollen, "extern" verwenden. Die einzige Ausnahme wäre, wenn garantiert wird, dass eine Header-Datei von einem und nur einem Modul enthalten ist.
Viele Projektmanager würden dann verlangen, dass eine solche Variable am Anfang des Moduls platziert wird und nicht in einer Header-Datei. Einige große Projekte, wie der Videospielemulator "Mame", erfordern sogar, dass eine solche Variable nur über der ersten Funktion angezeigt wird, die sie verwendet.
quelle
In C wird 'extern' für Funktionsprototypen impliziert, da ein Prototyp eine Funktion deklariert, die an einer anderen Stelle definiert ist. Mit anderen Worten, ein Funktionsprototyp verfügt standardmäßig über eine externe Verknüpfung. Die Verwendung von 'extern' ist in Ordnung, aber redundant.
(Wenn eine statische Verknüpfung erforderlich ist, muss die Funktion sowohl im Prototyp als auch im Funktionsheader als 'statisch' deklariert werden. Diese sollten sich normalerweise beide in derselben C-Datei befinden.)
quelle
Ein sehr guter Artikel, in dem ich über das
extern
Schlüsselwort gekommen bin , zusammen mit den Beispielen: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/Ich stimme jedoch nicht zu, dass die Verwendung
extern
in Funktionsdeklarationen überflüssig ist. Dies soll eine Compilereinstellung sein. Daher empfehle ich, dieextern
in den Funktionsdeklarationen zu verwenden, wenn dies erforderlich ist.quelle
Wenn jede Datei in Ihrem Programm zuerst zu einer Objektdatei kompiliert wird, werden die Objektdateien miteinander verknüpft
extern
. Es sagt dem Compiler: "Diese Funktion existiert, aber der Code dafür ist woanders. Keine Panik."quelle
Alle Deklarationen von Funktionen und Variablen in Header-Dateien sollten sein
extern
.Ausnahmen von dieser Regel sind Inline-Funktionen, die im Header definiert sind, und Variablen, die - obwohl im Header definiert - lokal für die Übersetzungseinheit sein müssen (die Quelldatei, in die der Header aufgenommen wird): Dies sollten sein
static
.In Quelldateien
extern
sollte nicht für Funktionen und Variablen verwendet werden, die in der Datei definiert sind. Stellen Sie lokalen Definitionen einfach voranstatic
und tun Sie nichts für gemeinsam genutzte Definitionen - sie sind standardmäßig externe Symbole.Der einzige Grund für die Verwendung
extern
in einer Quelldatei besteht darin, Funktionen und Variablen zu deklarieren, die in anderen Quelldateien definiert sind und für die keine Header-Datei bereitgestellt wird.Das Deklarieren von Funktionsprototypen
extern
ist eigentlich nicht erforderlich. Einige Leute mögen es nicht, weil es nur Platz verschwendet und Funktionsdeklarationen bereits dazu neigen, Liniengrenzen zu überschreiten. Andere mögen es, weil auf diese Weise Funktionen und Variablen auf die gleiche Weise behandelt werden können.quelle
extern
ist optional für Funktionsdeklarationen, aber ich behandle Variablen und Funktionen gerne gleich - zumindest ist das das Vernünftigste, was ich mir einfallen lassen kann, da ich mich nicht genau erinnere, warum ich damit angefangen habe;)In anderen Quelldateien tatsächlich definierte Funktionen sollten nur in Headern deklariert werden . In diesem Fall sollten Sie extern verwenden, wenn Sie den Prototyp in einem Header deklarieren .
In den meisten Fällen sind Ihre Funktionen eine der folgenden (eher eine bewährte Methode):
quelle
Wenn Sie diese Funktion in einer anderen DLL oder Bibliothek definiert haben, so dass der Compiler auf den Linker zurückgreift, um sie zu finden. Ein typischer Fall ist, wenn Sie Funktionen über die Betriebssystem-API aufrufen.
quelle