Wie benutze ich das Schlüsselwort extern in C?

Meine Frage ist, wenn eine function mit dem Schlüsselwort extern in C referenziert werden soll.

Ich sehe nicht, wann dies in der Praxis genutzt werden sollte. Während ich ein Programm schreibe, werden alle functionen, die ich verwende, über die Header-Dateien zur Verfügung gestellt. Warum sollte es also sinnvoll sein, extern Zugriff auf etwas zu haben, das nicht in der Header-Datei verfügbar war?

Ich könnte darüber nachdenken, wie extern falsch funktioniert, und wenn ja, bitte korrigieren Sie mich.

Edit: Sollten Sie etwas extern , wenn es die Standarddeklaration ohne das Schlüsselwort in einer Header-Datei ist?

   

extern ” ändert die Verknüpfung. Mit dem Schlüsselwort wird angenommen, dass die function / Variable irgendwo anders verfügbar ist und die Auflösung an den Linker verschoben wird.

Es gibt einen Unterschied zwischen “extern” bei functionen und bei Variablen: Bei Variablen instanziiert sie nicht die Variable selbst, dh sie weist keinen Speicher zu. Dies muss woanders gemacht werden. Daher ist es wichtig, wenn Sie die Variable von woanders importieren möchten. Bei functionen sagt dies nur dem Compiler, dass die Verknüpfung extern ist. Da dies der Standardwert ist (Sie verwenden das Schlüsselwort “static”, um anzugeben, dass eine function nicht über externe Verknüpfungen gebunden ist), müssen Sie sie nicht explizit verwenden.

extern sagt dem Compiler, dass diese Daten irgendwo definiert sind und mit dem Linker verbunden werden.

Mit Hilfe der Antworten hier und im Gespräch mit ein paar Freunden ist hier das praktische Beispiel eines Einsatzes von extern .

Beispiel 1 – um eine Falle zu zeigen:

 File stdio.h: int errno; /* other stuff...*/ 

 myCFile1.c: #include  Code... 

 myCFile2.c: #include  Code... 

Wenn myCFile1.o und myCFile2.o verknüpft sind, enthält jede der c-Dateien separate Kopien von errno . Dies ist ein Problem, da dasselbe Errno in allen verknüpften Dateien verfügbar sein soll.

Beispiel 2 – Die Lösung.

 File stdio.h: extern int errno; /* other stuff...*/ 

 File stdio.c int errno; 

 myCFile1.c: #include  Code... 

 myCFile2.c: #include  Code... 

Wenn nun sowohl myCFile1.o als auch MyCFile2.o durch den Linker verbunden sind, zeigen beide auf dasselbe errno . So lösen Sie die Implementierung mit extern .

Es wurde bereits festgestellt, dass das Schlüsselwort extern für functionen überflüssig ist.

Wie bei Variablen, die über Kompilierungseinheiten verteilt sind, sollten Sie sie in einer Headerdatei mit dem Schlüsselwort extern deklarieren und sie dann in einer einzigen Quelldatei ohne das Schlüsselwort extern definieren. Die einzige Quelldatei sollte die Datei sein, die den Namen der Header-Datei teilt.

In C wird “extern” für functionsprototypen impliziert, da ein Prototyp eine function deklariert, die anderswo definiert ist. Mit anderen Worten, ein functionsprototyp hat standardmäßig eine externe Verknüpfung; die Verwendung von ‘extern’ ist in Ordnung, aber überflüssig.

(Wenn eine statische Verknüpfung erforderlich ist, muss die function sowohl in ihrem Prototyp- als auch in ihrem functionskopf als ‘statisch’ deklariert werden, und diese sollten sich normalerweise beide in derselben .c-Datei befinden).

Viele Jahre später entdecke ich diese Frage. Nachdem ich alle Antworten und Kommentare gelesen hatte, konnte ich ein paar Details klären … Das könnte für Leute nützlich sein, die durch die Gogglesuche kommen.

Die Frage bezieht sich speziell auf die Verwendung von “extern” -functionen, daher werde ich die Verwendung von “extern” mit globalen Variablen ignorieren.

Lassen Sie uns 3 functionsprototypen definieren

 //-------------------------------------- //Filename: "my_project.H" extern int function_1(void); static int function_2(void); int function_3(void); 

Die Header-Datei kann wie folgt vom Hauptquellcode verwendet werden

 //-------------------------------------- //Filename: "my_project.C" #include "my_project.H" void main(void){ int v1 = function_1(); int v2 = function_2(); int v3 = function_3(); } int function_2(void) return 1234; 

Um kompilieren und verknüpfen zu können, müssen wir “function_2″ in derselben Quellcodedatei definieren, in der wir diese function aufrufen. Die beiden anderen functionen könnten in einem anderen Quellcode ” .C” definiert sein oder sie könnten sich in einer beliebigen Binärdatei ( .OBJ, * .LIB, * .DLL) befinden, für die wir möglicherweise keinen Quellcode haben.

Lassen Sie uns wieder die Überschrift “my_project.H” in eine andere “* .C” Datei einfügen, um den Unterschied besser zu verstehen. Im selben Projekt fügen wir die folgende Datei hinzu: // ————————————–

 //Filename: "my_big_project_splitted.C" #include "my_project.H" void old_main_test(void){ int v1 = function_1(); int v2 = function_2(); int v3 = function_3(); } int function_2(void) return 5678; int function_1(void) return 12; int function_3(void) return 34; 

Wichtige zu beachtende functionen: Wenn eine function in einer Headerdatei als “statisch” definiert ist, muss der Compiler / Linker in jedem Modul, das diese Include-Datei verwendet, eine Instanz einer function mit diesem Namen finden.

Eine function, 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 alle Aufrufe von “malloc” und “free”, um die function zur Erkennung von Speicherverlusten hinzuzufügen.

Der Spezifizierer “extern” wird für functionen nicht wirklich benötigt. Wenn “static” nicht gefunden wird, wird eine function immer als “extern” angenommen.

“Extern” ist jedoch nicht der Standardwert 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 eine Header-Datei garantiert von einem und nur einem Modul enthalten ist.

Viele Projektmanager würden dann verlangen, dass eine solche Variable am Anfang des Moduls platziert wird, nicht innerhalb einer Header-Datei. Einige große Projekte, wie der Videospiel-Emulator “Mame”, erfordern sogar, dass eine solche Variable nur über der ersten function erscheint, die sie verwendet.

Ein sehr guter Artikel über das extern Keyword, zusammen mit den Beispielen: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

Allerdings stimme ich nicht überein, dass die Verwendung von extern in functionsdeklarationen redundant ist. Dies soll eine Compiler-Einstellung sein. Daher empfehle ich, das extern in den functionsdeklarationen zu verwenden, wenn es benötigt wird.

Wenn jede Datei in Ihrem Programm zuerst in eine Objektdatei kompiliert wird, dann werden die Objektdateien miteinander verknüpft, Sie benötigen extern . Es sagt dem Compiler “Diese function existiert, aber der Code dafür ist woanders. Keine Panik.”

Alle Deklarationen von functionen und Variablen in Header-Dateien sollten extern .

Ausnahmen von dieser Regel sind Inline-functionen, die im Header definiert sind und Variablen, die – obwohl in der Kopfzeile definiert – für die Übersetzungseinheit lokal sein müssen (die Quelldatei, in die der Header aufgenommen wird): Diese sollte static .

In Quelldateien sollte extern nicht für in der Datei definierte functionen und Variablen verwendet werden. Setzen Sie lokale Definitionen einfach mit static und tun Sie nichts für gemeinsame Definitionen – sie sind standardmäßig externe Symbole.

Der einzige Grund, extern in einer Quelldatei zu verwenden, besteht darin, functionen und Variablen zu deklarieren, die in anderen Quelldateien definiert sind und für die keine Header-Datei bereitgestellt wird.


Das Deklarieren von functionsprototypen extern ist eigentlich nicht notwendig. Manche Leute mögen es nicht, weil es nur Platz verschwenden wird und functionserklärungen bereits eine Tendenz haben, die Grenzen des Überlaufs zu überschreiten. Andere mögen es, weil auf diese Weise functionen und Variablen auf die gleiche Weise behandelt werden können.

Wenn Sie diese function in einer anderen DLL oder einer anderen DLL definiert haben, wird der Compiler zum Linker verschoben, um ihn zu finden. Ein typischer Fall ist, wenn Sie functionen von der OS-API aufrufen.

functionen, die tatsächlich in anderen Quelldateien definiert sind, sollten nur in Headern deklariert werden . In diesem Fall sollten Sie extern verwenden, wenn Sie den Prototyp in einer Kopfzeile deklarieren .

Die meiste Zeit sind Ihre functionen eine der folgenden (mehr wie eine Best Practice):

  • statisch (normale functionen, die außerhalb der .c-Datei nicht sichtbar sind)
  • static inline (Inlines aus C- oder H-Dateien)
  • extern (Deklaration in Kopfzeilen der nächsten Art (siehe unten))
  • [kein Schlüsselwort] (normale functionen, auf die mit externen Deklarationen zugegriffen werden soll)