Referencia indefinida a 'pow' y 'floor'


124

Estoy tratando de hacer una calculadora de Fibonacci simple en C, pero cuando compila gccme dice que me faltan las funciones pow y floor. Que pasa

Código:

#include <stdio.h>
#include <math.h>

int fibo(int n);

int main() {
        printf("Fib(4) = %d", fibo(4));
        return 0;
}

int fibo(int n) {
        double phi = 1.61803399;

        return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

Salida:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status

Como la precisión de coma flotante no es infinita, esto dará respuestas incorrectas para valores no tan grandes den
vonbrand


Parece que existe una solución aún más fácil, simplemente use g ++ en su lugar: g ++ fib.c -o fibo
OrenIshShalom

Respuestas:


242

Necesita compilar con la bandera de enlace -lm, así:

gcc fib.c -lm -o fibo

Esto le dirá a gcc que vincule su código con la biblioteca matemática. Solo asegúrese de colocar la bandera después de los objetos que desea vincular.


77
¿Podría explicar cómo calcular la letra para poner después de -l?
Gabriele Cirulli

48
Busque en / lib o / usr / lib. Todas las bibliotecas se nombran lib<name>.ao lib<name>.so- es el "<nombre>" que coloca después de -l. En este caso, se nombra la biblioteca matemática libm.so, así que la llamamos -lm.
enms.

3
¡Gracias! He estado buscando en Google durante los últimos 30 minutos y esta es la primera referencia que dice vincular las bibliotecas después de los objetos
Dave Baghdanov

También se puede utilizar para contar LD_PRELOAD enlazador ld tiempo de ejecución para incluir libm.so en el mapa de memoria y símbolo de la tabla del proceso, por lo que estos símbolos se cargan y todo funciona como se esperaba
debuti

Gracias por la respuesta. Pero, ¿alguien puede decirme por qué en el caso de los códigos con algunas líneas está bien incluso si no incluyo -lm durante la compilación?
MItrajyoti Kusari

24

Agregue -lm a sus opciones de enlace, ya que pow () y floor () son parte de la biblioteca matemática:

gcc fib.c -o fibo -lm

9

Para el beneficio de cualquiera que lea esto más adelante, debe vincularlo como Fred dijo:

gcc fib.c -lm -o fibo

Una buena manera de averiguar qué biblioteca necesita vincular es verificando la página de manual si existe. Por ejemplo, man powy man floorambos te dirán:

Enlace con -lm.

Una explicación para vincular la biblioteca matemática en la programación en C - Vinculación en C


8

En cuanto a la respuesta proporcionada por Fuzzy:

De hecho, tuve que hacer algo un poco diferente.

Proyecto -> Propiedades -> C / C ++ Build -> Configuración -> GCC C Linker -> Bibliotecas

Haga clic en el pequeño ícono de agregar verde, escriba my presione OK. Todo en esta ventana se ha aplicado automáticamente, ya que es una biblioteca.


6

Encontrar el punto donde agregar el -lm en Eclipse-IDE es realmente horrible, así que me llevó algo de tiempo.

Si alguien más también usa Edlipse, esta es la forma de agregar el comando:

Proyecto -> Propiedades -> C / C ++ Build -> Configuración -> GCC C Linker -> Misceláneo -> Banderas de Linker: en este campo agregue el comando -lm


0

Todas las respuestas anteriores están incompletas, el problema aquí radica en el vinculador en ldlugar del compilador collect2: ld returned 1 exit status. Cuando está compilando su fib.cobjeto a:

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
                 U floor
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pow
                 U printf

Donde nmenumera los símbolos del archivo objeto. Puede ver que esto se compiló sin un error, pero pow, floory las printffunciones tienen referencias indefinidas, ahora si intento vincular esto al ejecutable:

$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

Estoy obteniendo una salida similar a la que obtienes. Para resolver eso, necesito decirle al vinculador dónde buscar referencias powy floor, para este propósito, usaré el -lindicador del vinculador mque proviene de la libm.sobiblioteca.

$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t 
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
                 U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
                 U pow@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__

Ahora puede ver, las funciones pow, floorestán vinculados a GLIBC_2.2.5.

El orden de los parámetros también es importante, a menos que su sistema esté configurado para usar bibliotecas compartidas de manera predeterminada, mi sistema no lo es, así que cuando emito

$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

Nota -lmbandera antes del archivo de objeto. En conclusión, agregue una -lmbandera después de todas las demás banderas y parámetros, para estar seguro.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.