Ich versuche ein kleines Beispiel über die statische externe Variable und ihre Verwendung. Die statische Variable hat lokalen Geltungsbereich, und die externe Variable hat einen globalen Geltungsbereich.
static5.c
%Vor%static5.h
%Vor%gcc static5.c statisch5.h
o / p:
%Vor%BEARBEITET
Das richtige Programm:
%Vor%Das funktioniert ganz gut. Aber das ist in einer einzigen Kompilationseinheit kompiliert. Daher könnte auf die statische Variable zugreifen. In der gesamten Übersetzungseinheit können wir die statische Variable nicht mit der externen Variable verwenden.
Denken Sie daran (zitiert Eli Bendersky):
- Eine statische Variable innerhalb einer Funktion behält ihren Wert zwischen Aufrufe.
- Eine statische globale Variable oder Funktion wird nur in "gesehen" die Datei, die in
deklariert ist
static int m = 25;
bedeutet in Ihrem Code, dass m
's nur auf diese Datei beschränkt ist , dh sie ist nur in static5.c
und nirgendwo sonst sichtbar.
Wenn Sie m
außerhalb von static5.c
verwenden möchten, entfernen Sie das Schlüsselwort static
aus der Deklaration der Variablen.
Für eine kanonische Erklärung, zusammen mit einem Beispiel, siehe diese Antwort von Eli Bendersky
BEARBEITEN: (nach Empfehlung von Klas) ** Der eigentliche Bereich ist eine Kompilierungseinheit, nicht die Quelldatei. Die Kompilierungseinheit ist die Art und Weise, wie die Datei nach dem Präprozessorschritt aussieht
static
hat eine sehr einfache Logik. Wenn eine Variable static
ist, bedeutet dies, dass es sich um eine globale Variable handelt, deren Umfang jedoch auf den Bereich beschränkt ist, in dem sie definiert ist (d. H. Nur dort sichtbar). Zum Beispiel:
Sehen wir uns jetzt an, was der C11-Standard in Bezug auf static
und extern
(Betonung meiner) sagt:
6.2.2.3
Wenn die Deklaration eines Dateibereichsbezeichners für ein Objekt oder eine Funktion den Speicherklassenbezeichner
static
enthält, hat der Bezeichner eine interne Verknüpfung.6.2.2.4
Für einen Bezeichner, der mit dem Speicherklassenbezeichner
extern
in einem Bereich deklariert wurde, in dem eine vorherige Deklaration dieses Bezeichners sichtbar ist, wenn die vorherige Deklaration eine interne oder externe Verknüpfung angibt Bezeichner bei der späteren Deklaration entspricht der bei der vorherigen Deklaration angegebenen Verknüpfung. Wenn keine vorherige Deklaration angezeigt wird oder wenn die vorherige Deklaration keine Verknüpfung angibt, hat der Bezeichner eine externe Verknüpfung. p>6.2.2.7
Wenn innerhalb einer Übersetzungseinheit dieselbe Kennung mit interner und externer Verknüpfung angezeigt wird, ist das Verhalten nicht definiert.
So sagt der Standard zuerst, wenn Sie haben:
%Vor% dann würde die zweite Deklaration (mit extern
) die erste betrachten und am Ende wäre m
immer noch static
.
Wenn jedoch in anderen Fällen Deklarationen mit interner und externer Verknüpfung vorliegen, ist das Verhalten nicht definiert. Das lässt uns eigentlich nur eine Option:
%Vor%, d. h. extern
deklaration vor static
deklaration. gcc war nett genug, um Ihnen in diesem Fall undefined behaviour Fehler zu geben.
Das Problem ist genau wie in der Fehlermeldung angegeben. m
wird als normales int
deklariert, wird aber später als static int
definiert.
extern
weist den Compiler / Linker an, nach der Variablen in der globalen Variablentabelle zu suchen.
static
(außerhalb einer Funktion) weist den Compiler an, die Variable aus der globalen Variablentabelle auszuschließen.
Siehst du den Konflikt?
Um das Problem zu beheben, entfernen Sie entweder das Schlüsselwort static
aus der Definition oder verschieben Sie die Definition über die Einbindung von static5.h
.
Es sollte beachtet werden, dass die Art und Weise, wie Sie Ihre Dateien entworfen haben, nicht als Best Practice gilt. Include-Dateien enthalten normalerweise keine Funktionen.
Entfernen Sie das Schlüsselwort static, während m deklariert wird, und die Fehler werden entfernt, und Sie erhalten die Antwort als 50. Das Schlüsselwort static lässt den Bereich innerhalb der Datei einschränken.
Tags und Links c