24

我正在尝试在 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 呢?

4

1 回答 1

43

对我来说,这看起来像一个错误。这个简单的案例展示了同样的错误:

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 编写示例代码的人也没有!

The inline on the ChangeBits function means that that definition is to be used only for inlining. Not that the function should always be inlined. There must be another, non-inline definition available elsewhere in the application otherwise it's illegal. Hence the link error as no non-inline ChangeBits is provided.

The real solution is to declare ChangeBits as static inline since that tells the compiler that the definition is local to that translation unit only and there does not therefore need to be a non-inline definition.

More information on the LLVM page I linked to, though. Hope that helps!

于 2012-10-11T17:49:38.397 回答