2013-02-03 14 views
9

Eventuali duplicati:
Effects of the `extern` keyword on C functionsconfusione per quanto riguarda extern con definizioni di funzioni in C

Ok, quindi per qualche ora ora ho letto molto su ciò che significa la parola chiave extern. E c'è un'ultima cosa che mi dà fastidio a non finire che non riesco a trovare alcuna informazione su. Per quanto ho capito la parola extern fondamentalmente dice al compilatore che la variabile o una funzione è solo una dichiarazione e che è definito da qualche parte, in modo che non si deve preoccupare che, il linker gestirlo.

e l'avviso generato dal compilatore (sto usando gcc 4.2.1) durante la digitazione questo:

extern int var = 10; 

supporta questo. Con extern questo dovrebbe essere una dichiarazione solo in modo che non è corretto.

Tuttavia, la cosa che mi confonde è l'assenza di un avvertimento o nulla quando si digita questo:

extern int func() {return 5;} 

Questa è una definizione, e dovrebbe generare lo stesso avvertimento, ma non è così. L'unica spiegazione per questo sono stato in grado di trovare qui è che la definizione sostituisce la parola chiave extern. Tuttavia, seguendo questa logica, perché non la sovrascrive quando è una definizione di variabile? Oppure la parola chiave ha un significato speciale quando viene utilizzata con le variabili?

sarei molto grato se qualcuno ha spiegato questo a me. Grazie!

+3

l'ultimo punto e virgola mi sta infastidendo. –

+1

Vedere se [questo collegamento] (http://stackoverflow.com/questions/856636/effects-of-the-extern-keyword-on-c-functions) aiuta. –

+1

Il problema deve essere l'inizializzazione della variabile – nabroyan

risposta

5

Il extern parola chiave ha infatti un significato speciale solo quando viene utilizzato con le variabili.Utilizzando extern con prototipi di funzione è del tutto facoltativo:

extern void foo(int bar); 

è equivalente a

void foo(int bar); 

Quando si dichiara/definendo una funzione, si hanno due opzioni:

  1. forniscono solo una dichiarazione (cioè un prototipo), oppure
  2. Fornire una definizione, che funge anche da dichiarazione in assenza di un prototipo.

Con variabili, tuttavia, avete tre opzioni:

  1. forniscono solo una dichiarazione,
  2. fornire una definizione con l'inizializzatore di default: int var; senza la parte = 10, o
  3. fornire una definizione con uno specifico inizializzatore: int var = 10

Sin ce ci sono solo due opzioni per le funzioni, il compilatore può distinguere tra allora senza l'uso della parola chiave extern. Qualsiasi dichiarazione che non ha una parola chiave static è considerata extern per impostazione predefinita. Pertanto, la parola chiave extern viene ignorata con tutte le dichiarazioni o definizioni di funzione.

Con le variabili, tuttavia, la parola chiave è necessaria per distinguere tra il # 1 e il # 2. Quando si utilizza extern, è il numero 1; quando non usi extern, è # 2. Quando si tenta di aggiungere extern a # 3, si tratta di un avviso, poiché rimane una definizione e lo extern viene ignorato.

Tutto questo è in qualche modo semplificato: è possibile fornire dichiarazioni diverse volte nella stessa unità di compilazione e è possibile fornirle nell'ambito globale o nell'ambito di un blocco. Per i dettagli completi, consultare la sezione 6.7.9 5 dello standard C.

+0

Le dichiarazioni relative alle dichiarazioni dell'oggetto (non variabile) non sono corrette. Allo scope del file: 'int x;' è una definizione provvisoria di un oggetto con linkage esterno, 'extern int x; 'è una dichiarazione di un oggetto con linkage esterno,' int x = 3; 'e' extern int x = 3 ; 'sono entrambe le definizioni di un oggetto con collegamento esterno. Nell'ambito del blocco: 'int x;' è una definizione di un oggetto senza link, 'extern int x;' è una dichiarazione di un oggetto con linkage esterno, 'int x = 3;' è una definizione di un oggetto senza linkage e 'extern int x = 3;' non è consentito, da C 2011 6.7.9 5. ... –

+0

Quanto sopra presuppone che ciascuna dichiarazione sia la prima volta che l'identificatore appare in tale ambito. Altrimenti, ci sono delle complicazioni. Ad esempio, 'static int x; extern int x; 'è permesso, e il secondo' x' è uguale al precedente 'x'.Inoltre, sebbene alcuni compilatori emettano un avvertimento per 'extern int x = 3;' nell'ambito del file, è esplicitamente mostrato come valido nell'esempio in C 2011 6.9.2 4. –

+0

@EricPostpischil Ho modificato la risposta, grazie per i commenti . – dasblinkenlight

3

Tuttavia, seguendo tale logica, perché non lo sovrascrive quando è una definizione di variabile? Oppure la parola chiave ha un significato speciale quando viene utilizzata con le variabili?

La differenza tra le variabili e le funzioni che è

void foo(); 

è una dichiarazione di funzione , ma

int i; 

è un definizione della variabile.

Se la definizione della variabile è presente in più file, il compilatore genererà l'archiviazione per quella variabile più volte (e molto probabilmente si otterrà un errore del linker). Questo non è il caso per le funzioni.

+1

Penso che sia più confuso quando abbiamo 'extern int x = 1;' che sembra sia una dichiarazione che una definizione con un inizializzatore. –

+0

Nell'ambito del file, 'int i;' è una definizione provvisoria, non una definizione e non genera spazio di memorizzazione più volte né causa un errore di collegamento. –

Problemi correlati