2013-03-24 18 views
10

Ho il seguente codice sorgente che mi interessa.extern con definizione globale di variabile in c

#include <stdio.h> 
extern int foo; 
int foo = 32; 

int main() 
{ 
printf("%d", foo); 
} 

Questo perfettamente normale pezzo di codice, e quando compilo con

gcc -Wall -Wextra -pedantic foo.c 

ottengo nessun avviso.

E sembra strano, perché una variabile è definita sia come esterna che globale nello stesso file. Sono abbastanza sicuro che è facile per il linker trovare il riferimento per la variabile esterna nello stesso file, ma non sembra un errore di codifica? E se sì, perché il compilatore non lo avverte?

risposta

13

Non c'è niente di strano. Prima hai fatto una dichiarazione di una variabile (hai promesso al compilatore che esistesse) e poi l'hai effettivamente definita. Non c'è nessun problema in questo.

Inoltre, per impostazione predefinita, tutte le variabili che non sono locali alle funzioni e non sono definite come static sono extern.

+0

prima dichiarata poi definita può essere vista anche nella definizione della funzione come: 'void function (int n; char d [n], int n);' Sono corretto **? ** –

+0

@GrijeshChauhan corretto. Questo è il meccanismo che consente la creazione di programmi con parti compilate separatamente più piccole (file di oggetti e librerie). Codice e dati possono essere sparsi su un numero di file. –

8

Sembra che tu abbia frainteso cosa fa extern. extern semplicemente rende la dichiarazione solo una dichiarazione anziché una definizione.

int i; //definition of i 
extern int i; //declaration of i 

È perfettamente normale avere più dichiarazioni della stessa variabile, ma una sola definizione dovrebbe essere presente nell'intero programma. Confronta questo con una funzione

void f(void); //declaration 
void f(void) //definition(and redeclaration) 
{ 
} //definition 

Per utilizzare una variabile o una funzione, è sufficiente la sua dichiarazione. La sua definizione può apparire ovunque nel programma (il linker lo troverà). Ovunque può essere lo stesso file, un altro file o anche una libreria esterna.

7

E sembra weired, perché una variabile è definita sia come esterna che globale nello stesso file.

extern int foo; 

dice: dichiara senza definire un oggetto di tipo int nome foo.

int foo = 32; 

dichiara e definisce un oggetto di tipo int denominato foo con linkage esterno.

Non c'è alcuna contraddizione ed è valido codice C.

+0

Ma se foo è stato effettivamente dichiarato (come promesso da extern) in qualche altro file, il codice 'int foo = 32;' non sarebbe corretto. –

+0

@Armin: 'foo' può essere dichiarato tante volte e in tutti i file che vuoi (con o senza' extern'), ma non può esserci più di un'inizializzazione. – teppic

+0

@teppic non senza 'extern'. Alla fine di un'unità di traduzione, la (e) definizione (i) del (dei) tentativo (i) diventerà una definizione reale. Ed è un comportamento indefinito avere più definizioni di oggetti esterni con lo stesso nome. – ouah

2

La differenza è che il primo è una dichiarazione ->extern dichiara una variabile e dice che sarà disponibile da qualche parte. Puoi avere tutte le dichiarazioni che vuoi e quest'ultima è una definizione che deve esserci esattamente una volta.
Quindi non ci dovrebbero essere avvisi e nessun errore.

1

extern è un modo per dare visibilità ad una variabile che è definita altrove ...

extern è come una promessa ...

nell'esempio.h

extern int g;// promises that this will be in the object code to anything that includes example.h 

esempio. c

int g; 
Problemi correlati