Niezdefiniowane odniesienie do „pow” i „floor”


124

Próbuję zrobić prosty kalkulator Fibonacciego w C, ale podczas kompilacji gccmówi mi, że brakuje mi funkcji pow i floor. Co jest nie tak?

Kod:

#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));
}

Wynik:

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

Ponieważ precyzja zmiennoprzecinkowa nie jest nieskończona, da to błędne odpowiedzi dla niezbyt dużych wartościn
vonbrand


Wygląda na to, że istnieje jeszcze łatwiejsze rozwiązanie, po prostu użyj zamiast tego g ++: g ++ fib.c -o fibo
OrenIshShalom

Odpowiedzi:


242

Musisz skompilować się z flagą linku -lm, na przykład:

gcc fib.c -lm -o fibo

To powie gcc, aby połączyć twój kod z biblioteką matematyczną. Po prostu pamiętaj, aby umieścić flagę po obiektach, które chcesz połączyć.


7
Czy mógłbyś wyjaśnić, jak opracować literę umieszczaną po -l?
Gabriele Cirulli

48
Zajrzyj do / lib lub / usr / lib. Wszystkie biblioteki są nazwane lib<name>.alub lib<name>.so- to „<nazwa>”, którą wstawiasz po -l. W tym przypadku nazwa biblioteki matematycznej libm.so, więc ją nazywamy -lm.
AMS

3
Dzięki! Szukam w Google przez ostatnie 30 minut i jest to pierwsza wzmianka o powiązaniu bibliotek po obiektach
Dave Baghdanov,

Możesz również użyć LD_PRELOAD, aby powiedzieć konsolidatorowi środowiska wykonawczego ld, aby włączył libm.so do mapy pamięci i tabeli symboli procesu, aby te symbole zostały załadowane i wszystko działa zgodnie z oczekiwaniami
debuti

Dziękuję za odpowiedź. Ale czy ktoś może mi powiedzieć, dlaczego w przypadku kodów z kilkoma wierszami jest to w porządku, nawet jeśli nie dołączę -lm podczas kompilacji?
MItrajyoti Kusari

24

Dodaj -lm do opcji linków, ponieważ pow () i floor () są częścią biblioteki matematycznej:

gcc fib.c -o fibo -lm

9

Z korzyścią dla każdego, kto to przeczyta później, musisz połączyć się z tym, jak powiedział Fred:

gcc fib.c -lm -o fibo

Dobrym sposobem, aby dowiedzieć się, do której biblioteki chcesz linkować, jest sprawdzenie strony podręcznika, jeśli taka istnieje. Na przykład man powiman floor obie powie ci:

Połącz z -lm .

Wyjaśnienie łączenia biblioteki matematycznej w programowaniu w C - Łączenie w C


8

W odniesieniu do odpowiedzi udzielonej przez Fuzzy:

Właściwie musiałem zrobić coś nieco innego.

Projekt -> Właściwości -> C / C ++ Kompilacja -> Ustawienia -> GCC C Linker -> Biblioteki

Kliknij małą zieloną ikonę dodawania, wpisz mi naciśnij OK. Wszystko w tym oknie ma automatycznie zastosowane -l, ponieważ jest to biblioteka.


6

Znalezienie punktu, w którym dodać -lm w Eclipse-IDE jest naprawdę okropne, więc zajęło mi to trochę czasu.

Jeśli ktoś inny również używa Edlipse, oto sposób dodania polecenia:

Projekt -> Właściwości -> Kompilacja C / C ++ -> Ustawienia -> GCC C Linker -> Różne -> Flagi konsolidatora: w tym polu dodaj polecenie -lm


0

Wszystkie powyższe odpowiedzi są niekompletne, problem tkwi w konsolidatorze, lda nie w kompilatorze collect2: ld returned 1 exit status. Podczas kompilowania fib.cobiektu do obiektu:

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

Gdzie nmwyświetla symbole z pliku obiektowego. Możesz zobaczyć, że zostało to skompilowane bez błędu, ale pow, floori printffunkcje mają niezdefiniowane odniesienia, teraz, jeśli spróbuję połączyć to z plikiem wykonywalnym:

$ 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

Otrzymuję podobne wyniki. Aby to rozwiązać, muszę powiedzieć linkerowi, gdzie szukać odniesień pow, iw floortym celu użyję -lflagi linkera, z mktórą pochodzi z libm.sobiblioteki.

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

Możesz teraz zobaczyć, funkcje pow, z floorktórymi są połączoneGLIBC_2.2.5 .

Kolejność parametrów też jest ważna, chyba że twój system jest skonfigurowany do korzystania z bibliotek współdzielonych domyślnie, mój system nie jest, więc kiedy wydaję:

$ 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

Uwaga -lmflaga przed plikiem obiektu. Podsumowując -lm, dla pewności dodaj flagę po wszystkich innych flagach i parametrach.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.