2013-05-24 19 views
7

semplice problema:Semplice C degli errori in linea linker

dato il seguente programma:

#include <stdio.h> 

inline void addEmUp(int a, int b, int * result) 
{ 
    if (result) { 
     *result = a+b; 
    } 
} 

int main(int argc, const char * argv[]) 
{ 
    int i; 
    addEmUp(1, 2, &i); 

    return 0; 
} 

ottengo un errore di linker ...

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

Sembra come se non lo fa preoccuparsi di compilarlo.

non dovrebbe bisogno di essere static, non vorrei pensare, in base a quello che ho letto in:
Linker error inline function (come questo è in un oggetto diverso, e si occupano di 2 definizioni piuttosto che zero)

Questo è un link correlato, ma è C++ e non credo è buona prassi in std C per inserire il codice nell'intestazione:
inline function linker error

informazioni compilatore:

cc --version 
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) 
Target: x86_64-apple-darwin12.3.0 
Thread model: posix 
esempio

compilazione:

# cc main.c 
Undefined symbols for architecture x86_64: 
    "_addEmUp", referenced from: 
     _main in main-sq3kr4.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocatio 
+0

quale comando hai usato per compilare? –

+0

Che compilatore stai usando? – Evans

+0

è clang in xcode 4.6.2 –

risposta

11

paragrafo 7 della sezione 6.7.4 dice:

Qualunque funzione con collegamento interno può essere una funzione inline. Per una funzione con collegamento esterno, si applicano le seguenti restrizioni: Se una funzione è dichiarata con un identificatore di funzione inline, allora deve essere definita anche nella stessa unità di traduzione. Se tutte le dichiarazioni di ambito dei file per una funzione in un'unità di traduzione includono l'identificatore di funzione inline senza extern, la definizione in tale unità di traduzione è una definizione in linea . Una definizione in linea non fornisce una definizione esterna per la funzione e non vieta una definizione esterna in un'altra unità di traduzione. Una definizione in linea fornisce un'alternativa a una definizione esterna, che un traduttore può utilizzare per implementare qualsiasi chiamata alla funzione nella stessa unità di traduzione. Non è specificato se una chiamata alla funzione utilizza la definizione in linea o la definizione esterna.

Il file non contiene una definizione esterna di addEmUp, e il compilatore ha scelto di utilizzare la definizione esterna nella chiamata in main.

Fornire una definizione esterna o dichiararla come static inline.

+0

statico inline non ha funzionato (almeno non nel progetto reale, non ho provato il primo esempio) ... Ho trovato una macro specifica Objective-C che funziona, sono in procinto di in aggiornamento. –

+0

'static inline' _ought_ to work, comunque. Riesci a bollire abbastanza lontano che l'errore del linker rimane ma il codice è abbastanza piccolo per SO? –

+0

sì, funziona nell'esempio. upvote e rispondi! –

3

Prova ad aggiungere l'opzione "-O" al tuo comando del compilatore. Inlining è attivato solo quando l'ottimizzazione è abilitata.

+0

che toglie l'errore linker, ma non dovrebbe semplicemente ignorare la parola chiave se non è in linea ... poiché è solo un suggerimento comunque –

+0

Ecco cosa fa GCC. Clang cerca di rispettare C99, che sembra avere un'interpretazione leggermente diversa, ed è per questo che stai riscontrando questo problema. http://clang.llvm.org/compatibility.html # inline – Ziffusion

+0

buona ricerca +1 –