I am trying to compile the sample code "SonofGrab" using XCode 4.5.1 on OS X 10.8.
One function is defined like this in controller.m
inline uint32_t ChangeBits(uint32_t currentBits, uint32_t flagsToChange, BOOL setFlags);
This leads to this error message:
Undefined symbols for architecture x86_64: "_ChangeBits", referenced from: -[Controller awakeFromNib] in Controller.o [...] ld: symbol(s) not found for architecture x86_64
Removing the inlining of the function ChangeBits solves the problem, but why does the linker not find Changebits with the original definition ?
The linker can inline small functions in place of a branch instruction to that function. For the linker to be able to do this, the function (without the return instruction) must fit in the four bytes of the branch instruction.
When we should avoid the use of inline? We should not use functions that are I/O bound as inline functions. When large code is used in some function, then we should avoid the inline. When recursion is used, inline function may not work properly.
Compiler can ignore the request for inlining. Compiler may not perform inlining in such circumstances like: If a function contains a loop.
Inline function may increase efficiency if it is small. 2) If a function contains static variables. 3) If a function is recursive. 4) If a function return type is other than void, and the return statement doesn't exist in function body.
That to me, looks like a bug. This simple case exhibits the same error:
inline void foo() {} int main() { foo(); }
Yields:
$ 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)
That has got to be wrong!? Unless I'm totally missing something about inline
.
Edit: Oh no, wait, check out this - http://clang.llvm.org/compatibility.html#inline
Basically it appears I didn't understand inline
fully, either. And nor did the person writing that sample code at 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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With