statische Deklaration von m folgt nicht-statischen Deklaration

7

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.

    
Angus 11.06.2013, 10:08
quelle

4 Antworten

13

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

    
NlightNFotis 11.06.2013, 10:11
quelle
14

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:

  • Außerhalb einer Funktion: globale Variable, aber nur innerhalb der Datei sichtbar (eigentlich die Kompilierungseinheit)
  • Innerhalb einer Funktion: globale Variable, aber nur innerhalb der Funktion
  • sichtbar
  • (C ++) Innerhalb einer Klasse: globale Variable, aber nur für die Klasse
  • sichtbar

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.

    
Shahbaz 11.06.2013 12:06
quelle
3

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.

    
Klas Lindbäck 11.06.2013 10:43
quelle
2

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.

    
Santhosh Pai 11.06.2013 10:19
quelle

Tags und Links