2010-06-23 16 views
9

Ho un piccolo progetto in cui ho chiamato la stessa funzione di due nomi in due file sorgente diversi, ma mentre ho creato il progetto, il compilatore ha avuto esito negativo con "nome_funzione già definito in nomefile.obj".Come gestire il nome della funzione duplicata all'interno di C?

Perché non è possibile avere due funzioni con lo stesso nome in due file sorgente diversi? Pensavo che la funzione dovesse essere locale al file sorgente solo se quando l'avessimo dichiarata nel file di intestazione diventasse globale.

E tranne che per cambiare il nome del file, c'è qualche altra elegante soluzione per il nome di una funzione duplicata nel linguaggio di programmazione C?

+0

Ecco perché uso sempre nomi veramente significativi per variabili e funzioni. Se quelle due funzioni stanno facendo esattamente la stessa cosa, allora non hai bisogno di una di esse. Se stanno facendo cose diverse, dai a ciascuno un nome significativo che rifletta quello che fa. Chiunque debba mantenere il tuo codice ti ringrazierà. Le probabilità sono, che sarai tu. – Mawg

risposta

28

In C, una funzione ha portata globale per impostazione predefinita. Per limitare il suo ambito, utilizzare la parola chiave static per renderla privata di un modulo.

Il ruolo del file di intestazione è solo per pubblicizzare la funzione insieme alla sua firma per altri moduli.

Tutti i nomi globali devono (con alcune avvertenze) essere unici. Questo ha senso perché quel nome è ciò che viene utilizzato dal linker per connettere una chiamata di funzione all'implementazione della funzione stessa.

I nomi con ambito statico e locale devono essere solo univoci nel loro ambito.

+7

Consiglio: Segna tutte le funzioni che puoi come 'statico'. Renderà anche più semplice l'ottimizzatore del compilatore, ad esempio per scegliere funzioni in linea e simili. – u0b34a0f6ae

2

L'elegante soluzione è lo spazio dei nomi introdotto in C++. La soluzione, se ci sono poche chiamate a func_name è prendere uno, rinominarlo e ricompilare.

soluzione

Qualcosa hackerous ma veloce potrebbe essere questo:

//In one of the two source files and any file that calls it 

//if your functions is something like this 
//void func_name(int) { ... } 
//Add the following line 
#define func_name SOME_UNIQUE_FUNC_NAME 
+4

Dichiarare statico è la soluzione migliore come suggerito da RBerteig. Lascio la mia risposta nella speranza che possa essere utile in ogni caso a qualcuno. – user347594

+0

è stato utile con un problema simile che stavo affrontando. Grazie. – FilipeCanatto

4

Dichiarare la funzione static per renderla locale al file. In C, ogni nome identificativo deve essere univoco.

5

Why could not I have two function with the same name in two differenct source file?

Becuase il linker ha bisogno di sapere che si intende quando si fa riferimento a esso.

Imagaien che a.h e b.h entrambi difettosi my_function(). Il compilatore genera codice per entrambi. Ora immagina che c.c chiami my_function() - come fa il linker a sapere quale delle due versioni della funzione dovrebbe essere chiamata?

5

Se qualche cosa è dichiarata nel file di intestazione o nel file di origine non fa assolutamente alcuna differenza per il compilatore. In effetti, il compilatore non conosce assolutamente nulla riguardo ai "file di intestazione", poiché i file di intestazione sono incorporati nei file di origine dal cosiddetto preprocessore, che funziona prima del compilatore. Nel momento in cui i file di origine (con i file di intestazione incorporati) arrivano al compilatore effettivo, non c'è modo di dire cosa era originariamente e cosa è stato inserito dai file di intestazione. Il file sorgente con tutti i file di intestazione incorporati in esso è chiamato unità di traduzione. Cioè il compilatore funziona correttamente con le unità di traduzione, non con alcuni file "sorgente" o "intestazione".

In linguaggio C tutti gli oggetti e le funzioni dichiarati nell'ambito del file hanno collegamento esterno per impostazione predefinita, il che significa che sono globali, univoci per l'intero programma. Quindi, hai pensato in modo errato. Le funzioni non sono locali solo per un file sorgente.

Se si desidera rendere locale una funzione (o un oggetto) in una singola unità di traduzione, è necessario eseguire alcuni passaggi espliciti. Devi dichiararlo come static. Dichiarandolo come statico si otterrà il collegamento interno , che in sostanza significa che diventa interno alla sua unità di traduzione.

La dichiarazione delle funzioni static funziona solo se entrambi devono essere locali alle proprie unità di traduzione. Se questo non è il caso, cioè se almeno una delle funzioni dovrebbe essere una funzione accessibile a livello globale (collegabile), allora non hai altra scelta che rinominare una delle funzioni.

Problemi correlati