2014-06-26 8 views
12

Wiki sagt:Wie definiert man externe Variable mit Deklaration?

Das extern Schlüsselwort bedeutet "ohne definieren, deklarieren". Mit anderen Worten, es ist eine Möglichkeit, eine Variable explizit zu deklarieren oder eine Deklaration ohne Definition zu erzwingen. Es ist auch möglich, eine Variable explizit zu definieren, d. H. Eine Definition zu erzwingen. Dies geschieht, indem Sie einer Variablen einen Initialisierungswert zuweisen.

Das heißt, eine extern Erklärung, dass die Variable initialisiert dient als eine Definition für diese Variable. So

/* Just for testing purpose only */ 
#include <stdio.h> 
extern int y = 0; 
int main(){ 
    printf("%d\n", y); 
    return 0; 
} 

gültig sein soll (compiled in C++11). Aber wenn es mit Optionen -Wall -Wextra -pedantic -std=c99 in GCC 4.7.2 kompiliert wird, erzeugt eine Warnung:

[Warning] 'y' initialized and declared 'extern' [enabled by default] 

welche nicht. AFAIK,

extern int y = 0; 

ist das Gleiche wie

int i = 0; 

Was falsch ist hier los?

+3

[This] (http://stackoverflow.com/questions/4268589/warning-in-extern-declaration) könnte auch helfen. Nicht die akzeptierte Antwort, sondern die von [AndreyT] (http://stackoverflow.com/users/187690/andreyt). Beachten Sie insbesondere die letzte Zeile der Antwort: _Schalten Sie diese Warnung in den Compiler-Einstellungen aus (und schreiben Sie dem GCC-Team bitte einen groben Brief) ._ – devnull

+0

@devnull; Ja .. – haccks

+0

@devnull; Mann. Du hast mich gerettet. Ich habe ungefähr eine Stunde damit verbracht! Vielen Dank :) – haccks

Antwort

5

Alle drei Versionen des Standard - ISO/IEC 9899: 1990, ISO/IEC 9899: 1999 und ISO/IEC 9899: 2011 - enthält ein Beispiel, in dem Abschnitt mit dem Titel Externe Objektdefinitionen (§ 6.7.2 von C90 und §6.9.2 von C99 und C11), die zeigt:

BEISPIEL 1

int i1 = 1;  // definition, external linkage 
static int i2 = 2; // definition, internal linkage 
extern int i3 = 3; // definition, external linkage 
int i4;   // tentative definition, external linkage 
static int i5;  // tentative definition, internal linkage 

Das Beispiel wird fortgesetzt, die extern int i3 = 3; Linie zeigt deutlich, dass der Standard zeigt an, dass es zugelassen werden soll. Beachten Sie jedoch, dass Beispiele in der Norm technisch nicht "normativ" sind (siehe das Vorwort in der Norm); Sie sind keine definitive Aussage darüber, was erlaubt ist und was nicht.

Das gesagt, verwenden die meisten Menschen die meiste Zeit extern und einen Initialisierer nicht.

+0

Ich habe Abschnitt 6.7.9 gesucht, um relevante Zitate oder Beispiele zu finden. – haccks

6

Dieser Code ist absolut gültig.

Aber jeder Compiler ist frei, zusätzliche auszustellen (informativ oder nicht) Diagnose:

(C99, 5.1.1.3p1 fn 8) „Natürlich ist eine Implementierung kostenlos eine beliebige Anzahl von Diagnose zu erzeugen, wie solange ein gültiges Programm noch korrekt übersetzt ist. "

Ein Compiler kann keine Diagnose ausgeben, wenn eine Integritätsbedingung oder eine Syntaxverletzung vorliegt.

EDIT:

Als devnull put in den OP Frage Kommentare, Joseph Myers von gcc Team in einer bug report Befragung erklärt diese Diagnose:

„Dies ist eine Art der Programmierung Warnung - der Code ist gültig, aber extrem unidiomatisch für C, da "extern" im Allgemeinen erwartet wird, dass die Deklaration keine Definition des Objekts liefert. "

+1

Ich denke, der relevanteste Teil des GCC-Fehlerberichts ist: "Dies ist eine Kodierungsstil-Warnung - der Code ist gültig, aber extrem unidiomatisch für C, da" extern "im Allgemeinen erwartet wird, dass die Deklaration keine Definition von liefert das Objekt." –

+1

Ich denke, es könnte sich lohnen, das Beispiel (das ich in meiner Antwort zitiere) von den C99/C11-Standards zum Fehlerbericht hinzuzufügen. –

+0

@ShafikYaghmour hat eine Bearbeitung hinzugefügt, um einen Teil des Inhalts des Fehlerberichts abzudecken. – ouah