2015-06-13 51 views
7

Ho 3 progetti: Server, client e Commons. La creazione di coppie di origini & nell'orario Commons non causa alcun problema e posso accedere liberamente alle funzioni dal server Server e Client."Definizione multipla", "prima qui definita" errori

Tuttavia, per qualche motivo fare ulteriori file sorgente/intestazione all'interno Server o client progetto provoca sempre multiple definition of (...) e first defined here errori.

Esempio:

commands.h (root dir del progetto client)

#ifndef COMMANDS_H_ 
#define COMMANDS_H_ 

#include "commands.c" 

void f123(); 

#endif /* COMMANDS_H_ */ 

commands.c (root dir del progetto clienti)

void f123(){ 

} 

main.c (in radice dir del progetto client)

#include "commands.h" 
int main(int argc, char** argv){ 

} 

Errori:

make: *** [Client] Error 1  Client 
first defined here    Client 
multiple definition of `f123' commands.c 

a secco, la ricostruzione dell'indice, progetti di ricostruzione non aiuta. Nemmeno riavvia il computer.

+6

No. Includere. '* .c'. File! –

+2

Più precisamente, non usare i file '# include'. – WhozCraig

+0

Non includere il corrispondente '* .c' dalle intestazioni causa altri errori nel mio progetto _Commons_. –

risposta

10

Il problema qui è che si è compreso nel commands.ccommands.h prima che il prototipo di funzione. Pertanto, il pre-processore C inserisce il contenuto di commands.c in commands.h prima del prototipo della funzione. commands.c contiene la definizione della funzione. Di conseguenza, la definizione della funzione finisce prima della dichiarazione della funzione che causa l'errore.

Il contenuto del commands.h dopo la fase di pre-processore simile a questa:

#ifndef COMMANDS_H_ 
#define COMMANDS_H_ 

// function definition 
void f123(){ 

} 

// function declaration 
void f123(); 

#endif /* COMMANDS_H_ */ 

Questo è un errore perché non è possibile dichiarare una funzione dopo la sua definizione in C.Se si è scambiato #include "commands.c" e la dichiarazione della funzione l'errore non dovrebbe avvenire perché, ora, il prototipo della funzione viene prima della dichiarazione della funzione.

Tuttavia, tra cui un file .c è una cattiva praticae dovrebbe essere evitato. Una soluzione migliore per questo problema sarebbe includere commands.h in commands.c e collegare la versione compilata del comando al file principale. Per esempio:

commands.h

ifndef COMMANDS_H_ 
#define COMMANDS_H_ 

void f123(); // function declaration 

#endif 

commands.c

#include "commands.h" 

void f123(){} // function definition 
+0

21598 visualizzazioni ... e 3 mi piace, scusa non capisco la tua soluzione, ho bisogno di aggiungere ".c" sì o sì ... – delive

+0

@delive La chiave è capire che non hai mai incluso il file .c. prova a includere il file .h corrispondente –

4

Non dovresti includere comandi.c nel file di intestazione. In generale, non dovresti includere i file .c. Piuttosto, commands.c dovrebbe includere commands.h. Come definito qui, il preprocessore C sta inserendo il contenuto di commands.c in commands.h dove è l'inclusione. Finisci con due definizioni di f123 in commands.h.

commands.h

#ifndef COMMANDS_H_ 
#define COMMANDS_H_ 

void f123(); 

#endif 

commands.c

#include "commands.h" 

void f123() 
{ 
    /* code */ 
} 
1

Forse incluso il file .c in più volte Makefile.

0

Sto aggiungendo questo A perché sono stato catturato con una versione bizzarra di questo che mi ha davvero graffiato la testa per circa un'ora finché non ho individuato la causa principale. Il mio carico è stato venendo a mancare a causa di molteplici ripetizioni di questo formato

<path>/linit.o:(.rodata1.libs+0x50): multiple definition of `lua_lib_BASE' 
<path>/linit.o:(.rodata1.libs+0x50): first defined here 

mi si rivelò essere un bug nella mia magia Makefile dove ho avuto un elenco di file C e utilizzando vpath ecc, in modo essa compila li avrebbe raccogliere dalla directory corretta nella gerarchia. Tuttavia un file C è stato ripetuto nell'elenco, alla fine di una riga e all'inizio della successiva, quindi il carico gcc generato dalla marca ha avuto il file .o due volte nella riga di comando. Durrrrh. Le molteplici definizioni provenivano da più occorrenze dello stesso file. Il linker ha ignorato i duplicati oltre agli inizializzatori statici!