2014-06-26 18 views
12

Wiki dice:Come definire la variabile extern insieme alla dichiarazione?

Il extern parola chiave significa "dichiarare senza definire". In altre parole, è un modo per dichiarare esplicitamente una variabile o forzare una dichiarazione senza una definizione. È anche possibile definire una variabile in modo esplicito, vale a dire forzare una definizione. Viene eseguito assegnando un valore di inizializzazione a una variabile.

Ciò significa, una dichiarazione extern che inizializza la variabile funge da definizione per quella variabile. Così,

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

dovrebbe essere valido (compiled in C++11). Ma quando si compila con opzioni -Wall -Wextra -pedantic -std=c99 in GCC 4.7.2, produce un avvertimento:

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

che non dovrebbe. Per quanto ne so,

extern int y = 0; 

è effettivamente la stessa

int i = 0; 

cosa sta andando male qui?

+3

[Questo] (http://stackoverflow.com/questions/4268589/warning-in-extern-declaration) potrebbe essere d'aiuto. Non la risposta accettata, ma quella di [AndreyT] (http://stackoverflow.com/users/187690/andreyt). Nota in particolare l'ultima riga della risposta: _ Disattiva questo avviso nelle impostazioni del compilatore (e, per favore, scrivi una lettera scortese al team GCC) ._ – devnull

+0

@devnull; Sì .. – haccks

+0

@devnull; Uomo. Mi hai salvato. Ne stavo scherzando circa un'ora! Grazie mille :) – haccks

risposta

5

Tutte e tre le versioni dello standard - ISO/IEC 9899: 1990, ISO/IEC 9899: 1999 e ISO/IEC 9899: 2011 - contenere un esempio nella sezione con il titolo definizioni degli oggetti esterni (§ 6.7.2 di C90 e §6.9.2 di C99 e C11), che mostra:

ESEMPIO 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 

L'esempio continua, ma la linea extern int i3 = 3; mostra chiaramente che la norma indica che dovrebbe essere consentito. Si noti, tuttavia, che gli esempi nello standard non sono tecnicamente "normativi" (si veda la prefazione nello standard); non sono una dichiarazione definitiva di ciò che è e non è permesso.

Detto questo, la maggior parte delle persone la maggior parte delle volte non usa extern e un inizializzatore.

+0

Cercavo nella sezione 6.7.9 per trovare qualsiasi citazione o esempio pertinente. – haccks

6

Questo codice è perfettamente valido.

Ma qualsiasi compilatore è libero di ulteriore problema (informativi o meno) la diagnostica:

(C99, 5.1.1.3p1 fn 8) "Certo, un'implementazione è libero di produrre un numero qualsiasi di diagnostica come finché un programma valido è ancora tradotto correttamente. "

Ciò che un compilatore non può fare non sta emettendo una diagnostica quando c'è un vincolo o una violazione della sintassi.

EDIT:

Come devnull put nei commenti questione OP, Joseph Myers da gcc squadra spiega in una bug report interrogatorio questa diagnostica:

"Questo è un avvertimento stile di codifica - il codice è valido, ma estremamente univoco per C da poiché "extern" generalmente significa che la dichiarazione non fornisce una definizione dell'oggetto. "

+1

Penso che la parte più rilevante del bug report di GCC sia: "Questo è un avvertimento di stile di codifica - il codice è valido, ma estremamente unidiomatico per C dato che" extern "generalmente significa che la dichiarazione non fornisce una definizione di l'oggetto." –

+1

Penso che valga la pena di aggiungere l'esempio (che cito nella mia risposta) dagli standard C99/C11 alla segnalazione di bug. –

+0

@ShafikYaghmour ha aggiunto una modifica per coprire parte del contenuto della segnalazione bug – ouah

Problemi correlati