链接内联函数的错误

ale*_*ail 22 xcode linker objective-c clang osx-mountain-lion

我试图在OS X 10.8上使用XCode 4.5.1编译示例代码"SonofGrab".

一个函数在controller.m中定义如下

inline uint32_t ChangeBits(uint32_t currentBits, uint32_t flagsToChange, BOOL setFlags);
Run Code Online (Sandbox Code Playgroud)

这会导致出现此错误消息:

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

删除函数ChangeBits的内联解决了问题,但为什么链接器找不到具有原始定义的Changebits?

mat*_*way 42

那对我来说,看起来像一个bug.这个简单的案例表现出同样的错误:

inline void foo() {}
int main() {
    foo();
}
Run Code Online (Sandbox Code Playgroud)

产量:

$ 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)
Run Code Online (Sandbox Code Playgroud)

这一定是错的!?除非我完全错过了什么inline.

编辑:哦不,等等,看看这个 - http://clang.llvm.org/compatibility.html#inline

基本上看起来我也完全不了解inline.那个人也没有在Apple上编写示例代码!

inlineChangeBits功能是指该定义仅适用于内联使用.并不是说应该总是内联函数.在应用程序的其他地方必须有另一个非内联定义,否则它是非法的.因此,链接错误不提供非内联ChangeBits.

真正的解决方案是声明ChangeBits为,static inline因为它告诉编译器该定义仅对该转换单元是本地的,因此不需要是非内联定义.

但是,有关我链接到的LLVM页面的更多信息.希望有所帮助!

  • 我遇到了这个问题,并且mattjgalloway的答案解决了它.为了更清楚,在Controller.m第71行中,在"内联"前添加"静态". (3认同)