2012-10-11 46 views
22

我想在OS X 10.8上使用XCode 4.5.1編譯示例代碼「SonofGrab」。內聯函數的鏈接錯誤

一個功能是Controller.m或者像這樣定義

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

這將導致該錯誤消息:

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

刪除功能ChangeBits的內聯解決了這個問題,但爲什麼用鏈接器找不到原始定義的Changebits?

回答

40

對我來說,看起來像一個錯誤。這個簡單的情況下表現出了同樣的錯誤:

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

產量:

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

那一定是錯的!?除非我完全錯過了inline

編輯:哦,不,等一下,看看這個 - http://clang.llvm.org/compatibility.html#inline

基本上它似乎我沒有完全理解inline,無論是。此人也沒有在Apple上寫示例代碼!

ChangeBits函數意味着該定義僅用於內聯。不是該函數應該總是內聯。在應用程序的其他地方必須有另一個非內聯定義,否則它是非法的。因此,提供鏈接錯誤,因爲不提供非內聯ChangeBits

真正的解決方案是將ChangeBits聲明爲static inline,因爲它告訴編譯器該定義僅適用於該翻譯單元,並且因此不需要是非內聯定義。

儘管如此,有關LLVM頁面鏈接的更多信息。希望有所幫助!

+1

我不記得在OS X 10.7上有相同的代碼示例有這個問題。鏗鏘聲有沒有改變這個代碼? – alecail

+0

可能因爲您以前使用過GCC或LLVM-GCC。 LLVM-GCC意味着與GCC兼容,即產生相同的結果。現在您完全使用了Clang,您將看到錯誤,正如我鏈接到的LLVM文檔中所描述的那樣。 – mattjgalloway

+3

我遇到了這個問題,mattjgalloway的答案解決了這個問題。爲了更清楚起見,在Controller.m第71行中,在「inline」前面添加「static」。 –