2012-10-11 9 views
22

Ich versuche den Beispielcode "SonofGrab" mit XCode 4.5.1 unter OS X 10.8 zu kompilieren.Verknüpfungsfehler für Inline-Funktionen

Eine Funktion wird wie folgt in Controller.m definiert

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

Dies führt zu dieser Fehlermeldung:

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

den inlining der Funktion ChangeBits Entfernen löst das Problem, aber warum funktioniert die Linker nicht Changebits mit der ursprünglichen Definition?

Antwort

40

Das sieht für mich wie ein Fehler aus. Dieser einfache Fall zeigt den gleichen Fehler:

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

Ausbeuten:

$ 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) 

, die zu Unrecht bekommen hat !? Es sei denn, ich vermisse etwas über inline.

Edit: Oh nein, warten Sie, lesen Sie in diesem - http://clang.llvm.org/compatibility.html#inline

Grundsätzlich scheint es, ich nicht inline voll, entweder verstanden. Und auch die Person, die diesen Beispielcode bei Apple geschrieben hat!

Die inline auf der ChangeBits Funktion bedeutet, dass diese Definition nur für Inlining verwendet werden soll. Nicht dass die Funktion immer inline sein sollte. Es muss eine andere Nicht-Inline-Definition an anderer Stelle in der Anwendung verfügbar sein, andernfalls ist sie illegal. Daher wird der Verbindungsfehler als nicht inline ChangeBits bereitgestellt.

Die echte Lösung besteht darin, ChangeBits als static inline zu deklarieren, da dies dem Compiler sagt, dass die Definition nur für diese Übersetzungseinheit lokal ist und daher keine Nicht-Inline-Definition sein muss.

Weitere Informationen auf der LLVM-Seite, mit der ich verlinkt bin. Ich hoffe, das hilft!

+1

Ich kann mich nicht erinnern, dieses Problem unter OS X 10.7 mit dem gleichen Codebeispiel zu haben. Gab es einige Veränderungen beim Klang, die diesen Code kaputt gemacht haben? – alecail

+0

Wahrscheinlich, weil Sie zuvor GCC oder LLVM-GCC verwendet haben. LLVM-GCC soll mit GCC kompatibel sein, d. H. Dieselben Ergebnisse liefern. Jetzt verwenden Sie Clang vollständig. Sie sehen den Fehler genau wie in den LLVM-Dokumenten beschrieben, mit denen ich verlinkt bin. – mattjgalloway

+3

Ich stieß auf dieses Problem und mattjgalloways Antwort löste es. Um noch deutlicher zu werden, fügen Sie in Controller.m, Zeile 71, "static" vor "inline" hinzu. –

Verwandte Themen