Undefinierter Verweis auf "pow" und "floor"

124

Ich versuche, einen einfachen Fibonacci-Rechner in C zu erstellen gcc, aber beim Kompilieren erfahre ich, dass mir die Pow- und Floor-Funktionen fehlen. Was ist los mit dir?

Code:

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

Ausgabe:

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
Gabriele Cirulli
quelle
Da die Gleitkommapräzision nicht unendlich ist, gibt dies falsche Antworten für nicht so große Werte vonn
vonbrand
Es scheint, dass es eine noch einfachere Lösung gibt, verwenden Sie stattdessen einfach g ++: g ++ fib.c -o fibo
OrenIshShalom

Antworten:

242

Sie müssen mit dem Link-Flag -lmwie folgt kompilieren :

gcc fib.c -lm -o fibo

Dadurch wird gcc angewiesen, Ihren Code mit der Math-Bibliothek zu verknüpfen. Stellen Sie einfach sicher, dass die Flagge hinter den Objekten steht, die Sie verknüpfen möchten.

Fred
quelle
7
Könnten Sie bitte erklären, wie Sie den Buchstaben nach -l ausarbeiten?
Gabriele Cirulli
48
Suchen Sie in / lib oder / usr / lib. Die Bibliotheken haben alle den Namen lib<name>.aoder lib<name>.so- es ist der "<Name>", den Sie nach dem eingeben -l. In diesem Fall heißt die Mathematikbibliothek libm.so, also nennen wir sie -lm.
Ams
3
Vielen Dank! Ich habe in den letzten 30 Minuten
gegoogelt
Sie können auch LD_PRELOAD verwenden, um ld Runtime Linker anzuweisen, libm.so in die Speicherzuordnung und Symboltabelle des Prozesses aufzunehmen, damit diese Symbole geladen werden und alles wie erwartet funktioniert
Debüt
Danke für die Antwort. Aber kann mir jemand sagen, warum es bei Codes mit ein paar Zeilen in Ordnung ist, auch wenn ich beim Kompilieren -lm nicht einbeziehe?
MItrajyoti Kusari
24

Fügen Sie -lm zu Ihren Linkoptionen hinzu, da pow () und floor () Teil der Mathematikbibliothek sind:

gcc fib.c -o fibo -lm
Yann Droneaud
quelle
9

Damit jemand dies später lesen kann, müssen Sie einen Link dazu erstellen, wie Fred sagte:

gcc fib.c -lm -o fibo

Eine gute Möglichkeit, um herauszufinden, welche Bibliothek Sie verknüpfen müssen, besteht darin, die Manpage zu überprüfen, falls eine vorhanden ist. Zum Beispiel man powund werden man floorIhnen beide sagen:

Link mit -lm.

Eine Erklärung zum Verknüpfen der Mathematikbibliothek in der C-Programmierung - Verknüpfen in C.

spike.barnett
quelle
8

In Bezug auf die Antwort von Fuzzy:

Ich musste tatsächlich etwas anderes machen.

Projekt -> Eigenschaften -> C / C ++ Build -> Einstellungen -> GCC C Linker -> Bibliotheken

Klicken Sie auf das kleine grüne Symbol zum Hinzufügen, geben Sie m ein und klicken Sie auf OK. Auf alles in diesem Fenster wird automatisch -l angewendet, da es sich um eine Bibliothek handelt.

Greg K.
quelle
6

Es ist wirklich schrecklich, den Punkt zu finden, an dem das -lm in Eclipse-IDE hinzugefügt werden kann, daher habe ich einige Zeit gebraucht.

Wenn jemand anderes auch Edlipse verwendet, können Sie den Befehl folgendermaßen hinzufügen:

Projekt -> Eigenschaften -> C / C ++ Build -> Einstellungen -> GCC C Linker -> Verschiedenes -> Linker-Flags: Fügen Sie in dieses Feld den Befehl -lm ein

Fuzzy
quelle
0

Alle obigen Antworten sind unvollständig, das Problem liegt hier ldeher im Linker als im Compiler collect2: ld returned 1 exit status. Wenn Sie Ihr fib.cto-Objekt kompilieren :

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

Wobei nmSymbole aus der Objektdatei aufgelistet werden. Sie können sehen, dass dies ohne Fehler kompiliert wurde, aber pow, floorund printfFunktionen haben undefinierte Referenzen, wenn ich jetzt versuchen werde, dies mit der ausführbaren Datei zu verknüpfen:

$ 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

Ich bekomme eine ähnliche Ausgabe, die du bekommst. Um das zu lösen, muss ich dem Linker mitteilen, wo nach Verweisen gesucht werden soll pow, und floorzu diesem Zweck werde ich das Linker- -lFlag verwenden, mit mdem aus der libm.soBibliothek stammt .

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

Sie können nun sehen, Funktionen pow, floorsind verknüpft GLIBC_2.2.5.

Die Reihenfolge der Parameter ist ebenfalls wichtig, es sei denn, Ihr System ist standardmäßig für die Verwendung gemeinsam genutzter Bibliotheken konfiguriert. Mein System ist dies jedoch nicht. Wenn ich also Folgendes ausführe:

$ 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

-lmFlag vor Objektdatei beachten . Fügen Sie abschließend -lmnach allen anderen Flags und Parametern ein Flag hinzu , um sicherzugehen.

klingenkp
quelle