2012-10-11 27 views
22

Estoy intentando compilar el código de muestra "SonofGrab" utilizando XCode 4.5.1 en OS X 10.8.Error de enlace para funciones en línea

Una función se define como esto en Controller.m

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

Esto conduce a este mensaje de error:

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

Extracción de la expansión en línea de los ChangeBits función soluciona el problema, pero ¿por qué el linker no encuentra Changebits con la definición original?

Respuesta

40

Eso me parece un error. Este caso simple exhibe el mismo error:

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

Rendimiento:

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

Eso tiene que ser malo !? A menos que me falta algo acerca de inline.

Editar: Oh no, espera, echa un vistazo a esto - http://clang.llvm.org/compatibility.html#inline

Básicamente, parece que no entendía inline totalmente, tampoco. ¡Y tampoco la persona que escribió ese código de muestra en Apple!

La inline en la función ChangeBits significa que esa definición se debe usar solo para alinear. No es que la función siempre deba estar en línea. Debe haber otra definición no en línea disponible en otra parte de la aplicación; de lo contrario, es ilegal. De ahí el error de enlace ya que no se proporciona ChangeBits no en línea.

La verdadera solución es declarar ChangeBits como static inline, ya que le dice al compilador que la definición es local para esa unidad de traducción solamente y, por lo tanto, no es necesario que haya una definición no en línea.

Más información en la página de LLVM a la que me he vinculado. ¡Espero que ayude!

+1

No recuerdo haber tenido este problema en OS X 10.7 con la misma muestra de código. ¿Hubo algunos cambios en el clang que rompieron este código? – alecail

+0

Probablemente porque antes usaba GCC o LLVM-GCC. LLVM-GCC pretende ser compatible con GCC, es decir, producir los mismos resultados. Ahora que está utilizando Clang por completo, está viendo el error exactamente como se describe en los documentos de LLVM a los que me he vinculado. – mattjgalloway

+3

Me encontré con este problema y la respuesta de mattjgalloway lo resolvió. Para ser más claros, en Controller.m, línea 71, agregue "static" delante de "inline". –

Cuestiones relacionadas