2011-08-25 14 views
8

Ecco l'offerta. Ho avuto due variabili globali identiche in due file .c diversi, non sono stati dichiarati come extern. Quindi ogni file .c dovrebbe aver visto la propria variabile, giusto?Due variabili con lo stesso nome e tipo, in due diversi file .c, compilare con gcc

Ma ho ottenuto un comportamento davvero strano, come se un file leggesse l'altra variabile di file (dopo averli collegati insieme). L'aggiunta del qualificatore "statico" a entrambe le definizioni di variabili sembrava risolvere questo problema.

Quindi quello che mi chiedo in realtà è che cosa è successo esattamente lì senza il qualificatore "statico"?

+1

Vedi anche http://stackoverflow.com/questions/1490693/tentativi-definizioni-in-c99-e-linking per aspetti difficili del collegamento est. –

+0

@Pascal La tua risposta è in realtà la più completa, peccato non posso contrassegnarla come accettata. Ho pensato a me stesso di fare qualcosa di simile a quello che hai fatto lì con 'nm '. L'unica cosa che mi viene in mente riguardo a questa situazione è che si tratta di un difetto importante nello standard, di cui si parla persino qui http://www.jetcafe.org/jim/c-style.html#need_extern. Voglio dire, chi diavolo ha pensato che sarebbe stato bello se il compilatore avesse assunto la qualifica "extern" ?? C++ sicuramente non fa una tale stupida ipotesi. – johndoevodka

risposta

18

Quindi ogni file .c dovrebbe aver visto la propria variabile, giusto?

Errore. In C, l'omissione di static da una dichiarazione implica il collegamento implicito extern.

Da C In poche parole:

Le dichiarazioni di funzione compilatore ossequio senza una classe di memoria specificatore come se inclusi l'extern specificatore. Allo stesso modo, qualsiasi identificatore di oggetto che si dichiara al di fuori di tutte le funzioni e senza un identificatore di classe di memoria ha external linkage.

+0

Grazie, non lo sapevo. Perché il compilatore non ha sollevato un errore o un avvertimento? – johndoevodka

+2

Solo per riferimento, sia Visual Studio 2008 che GCC 4.3.5 seguono questa regola. E ricompilare il codice con il compilatore C++ (cambiando in estensione .cpp in VC, o chiamando g ++ in linux) dà l'errore di collegamento "a definizione multipla". – Zac

0

Per quanto ne so, quando non si specifica né statico né extern, è compito del compilatore scegliere. E gcc in questo caso va per extern, quindi devi specificare static nel tuo caso.

Ho avuto lo stesso problema, a pochi anni fa :-) file di output

1

è generato facendo file oggetto di singolo file e poi li collega tra loro dal linker. Ora, quando si ha una variabile identica in due file diversi, il singolo file verrà compilato senza errori ma al momento del collegamento il linker otterrà due definizioni di variabile e genererà un errore. Ma nel caso dell'ambito statico di entrambe le variabili limitate per il file, ogni cosa funziona bene. Spero che lo troverai utile.

2

ALWAYS Inizializza la variabile globale, quindi il compilatore non considererà automaticamente il suo collegamento come extern. Il compilatore genera un errore durante la compilazione.

Ciò contribuirà ad evitare problemi casuali a base di codice grande, perché il nostro codice può usare qualcuno variabile altro dichiarato che ha un certo valore casuale (nel nostro punto di vista logico)

Problemi correlati