2013-08-28 25 views
7

Sto provando ad usare un makefile per compilare un programma che qualcun altro ha scritto, usando cygwin. Ricevo molti messaggi di errore, molti dei quali si lamentano di error: template with C linkage.Programma di compilazione contenente extern "C"

Dopo aver cercato un po 'sembra che il problema sia collegato a extern "C". Questa riga è contenuta nel file cygwin/usr/include/pthread.h, incluso in #include <pthread.h> in una delle intestazioni. E quando rimuovo questa linea, la maggior parte dei messaggi di errore scompare. Ma ce ne sono alcuni, del seguente tipo:

/usr/include/pthread.h:67:5: error: previous declaration of ‘int pthread_atfork(void (* )(),void (*)(), void (*)())’ with ‘C++’ linkage 

/usr/include/sys/unistd.h:136:5: error: conflicts with new declaration with ‘C’ linkage 

Qualcuno sa come risolvere questo problema? Mi piacerebbe sedermi e imparare tutte queste cose in dettaglio ma non ho tempo prima di aver bisogno di questo programma in esecuzione ..

+1

Non c'è molto che possiamo fare per aiutarti senza vedere il codice effettivo che stai cercando di compilare. –

+6

Non modificare 'pthread.h', che probabilmente ha ragione, è necessario capire perché si ottiene l'errore originale che probabilmente non è presente. Il primo candidato che vorrei cercare sono le macro. –

risposta

8

MODIFICA: in base allo scambio nei commenti, il colpevole era un file di intestazione nella directory di build (Endian.h) che era in conflitto con un file di sistema incluso /usr/include/endian.h. Veniva incluso al posto dell'intestazione del sistema e causava problemi di compilazione. I file erano in conflitto perché il caso è insignificante su Windows. La causa principale era quella suggerita nella risposta originale. Il costrutto extern C stava perdendo involontariamente nel codice C++, dove sono stati definiti i template, causando l'errore indicato.

Vorrei verificare la presenza di un costrutto di collegamento C "ciondolante" nei file di intestazione da qualche parte. Questo sarebbe nel codice che hai scritto (non in nessuna delle intestazioni di sistema, quelle sono probabilmente sicure).

codice nelle intestazioni è avvolto con,

sopra:

#ifdef __cplusplus 
extern "C" { 
#endif 

e in basso:

#ifdef __cplusplus 
} 
#endif 

Se la parte inferiore è mancante, l'effetto della metà superiore estende in codice in altre intestazioni involontariamente. Ciò causa problemi come quelli che stai incontrando.

+0

@ JonP.Harris La cosa strana è che, come ho detto, non ho scritto il codice da solo e sono positivo che funzioni per altre persone. Ho cercato il codice che hai menzionato nelle intestazioni, ma non riesco a trovarlo finora. Tuttavia, sospetto che gli autori usino linux, mentre io uso Windows, e facendo ricerche su Google sembra che ci possano essere dei problemi con pthread e cygwin su Windows? – jorgen

+1

@jorgen Quello che puoi fare è guardare l'output preelaborato. Esegui il comando del compilatore così com'è, ma sostituisci l'opzione "-c" con "-E". L'output dovrebbe andare in un file specificato con l'opzione "-o". Guardalo e, se vuoi, incolla il file da qualche parte e pubblica il link qui (se vuoi aiuto). – Ziffusion

+0

Grazie per il suggerimento! Il problema è che, guardando i makefile, non capisco molto di cosa sta succedendo, e non riesco a trovare il file menzionato che include _pthread.h_ e quindi inizia il problema .. – jorgen

7

Questo problema sorge quando il compilatore sta compilando un mix di codice C e C++. La sintassi externale "C" è un modo per dire al compilatore C++ che anche un compilatore C deve accedere a questa funzione. Il compilatore C non capisce questo uso di extern, così tipicamente si nasconde in questo modo:



    #ifdef __cplusplus 
    extern "C" { 
    #endif
void whatever();
#ifdef __cplusplus } #endif

Tuttavia, non si dovrebbe andare cambiando le intestazioni di sistema, le probabilità di quelli che sono sbagliate sono molto scarse. Più probabilmente uno dei tuoi intestazioni manca la parentesi di chiusura sopra.

1

Somiglianza con la risposta accettata, questo era un problema di nidificazione anche per me, ma non con ifdef/endif, quindi sto aggiungendo come riferimento per gli altri.

Nel mio caso, questo errore è stato causato da costrutti nidificati extern "C"; un file di intestazione contenente un costrutto extern "C" è stato incluso all'interno di un altroextern "C" costrutto, causando il nesting che ha confuso il compilatore/preprocessore.

File a.h:

#ifdef __cplusplus 
extern "C"{ 
#endif 

#include "b.h" 

#ifdef __cplusplus 
} 
#endif 

file b.h

#ifdef __cplusplus 
extern "C"{ 
#endif 

void someFunctionDeclaration(); 

#ifdef __cplusplus 
} 
#endif 

Spostamento del #include "b.h" al di fuori del costrutto a.hextern "C" risolve il problema.