2012-10-11 19 views
22

Sto cercando di compilare il codice di esempio "SonofGrab" utilizzando XCode 4.5.1 su OS X 10.8.Errore di collegamento per funzioni inline

Una funzione è definita come questo in controller.m

inline uint32_t ChangeBits(uint32_t currentBits, uint32_t flagsToChange, BOOL setFlags); 

Questo porta a questo messaggio di errore:

Undefined symbols for architecture x86_64: 
"_ChangeBits", referenced from: 
-[Controller awakeFromNib] in Controller.o 
[...] 
ld: symbol(s) not found for architecture x86_64 

rimozione della messa in linea delle ChangeBits funzione risolve il problema, ma perché fa il linker non trova i cambiamenti con la definizione originale?

risposta

40

Questo per me sembra un insetto. Questo semplice caso presenta lo stesso errore:

inline void foo() {} 
int main() { 
    foo(); 
} 

Resa:

$ clang test-inline.c 
Undefined symbols for architecture x86_64: 
    "_foo", referenced from: 
     _main in test-inline-MfUY0X.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Questo ha ottenuto di essere sbagliato !? A meno che non mi manchi completamente qualcosa su inline.

Edit: Oh no, aspetta, controlla questo - http://clang.llvm.org/compatibility.html#inline

In sostanza sembra che non capivo inline completamente, neanche. E nemmeno la persona che ha scritto quel codice di esempio su Apple!

Il inline sulla funzione ChangeBits significa che quella definizione deve essere utilizzata solo per inlining. Non che la funzione dovrebbe essere sempre in linea. Ci deve essere un'altra definizione non in linea disponibile altrove nell'applicazione altrimenti è illegale. Di conseguenza, l'errore di collegamento non è fornito da ChangeBits non in linea.

La vera soluzione è dichiarare ChangeBits come static inline poiché ciò indica al compilatore che la definizione è locale solo per quell'unità di traduzione e che quindi non è necessario che sia una definizione non in linea.

Ulteriori informazioni sulla pagina LLVM a cui mi sono collegato. Spero possa aiutare!

+1

Non ricordo di aver riscontrato questo problema su OS X 10.7 con lo stesso codice di esempio. Sono stati apportati alcuni cambiamenti al clang che hanno infranto questo codice? – alecail

+0

Probabilmente perché prima stavate usando GCC o LLVM-GCC. LLVM-GCC è pensato per essere compatibile con GCC, cioè produrre gli stessi risultati. Ora stai usando completamente Clang, stai vedendo l'errore come nell'esatta cosa descritta nei documenti LLVM a cui mi sono collegato. – mattjgalloway

+3

Mi sono imbattuto in questo problema e la risposta di mattjgalloway l'ha risolto. Giusto per essere più chiaro, in Controller.m, riga 71, aggiungi "statico" davanti a "in linea". –

Problemi correlati