Référence non définie à «pow» et «floor»

124

J'essaie de faire une simple calculatrice de fibonacci en C mais lors de la compilation gcc, cela me dit qu'il me manque les fonctions pow et floor. Qu'est-ce qui ne va pas?

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

Production:

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
la source
Comme la précision en virgule flottante n'est pas infinie, cela donnera de mauvaises réponses pour des valeurs pas si grandes den
vonbrand
Il semble qu'une solution encore plus simple existe, utilisez simplement g ++ à la place: g ++ fib.c -o
fibo

Réponses:

242

Vous devez compiler avec l'indicateur de lien -lm, comme ceci:

gcc fib.c -lm -o fibo

Cela indiquera à gcc de lier votre code à la bibliothèque mathématique. Assurez-vous simplement de placer le drapeau après les objets que vous souhaitez lier.

Fred
la source
7
Pourriez-vous s'il vous plaît expliquer comment élaborer la lettre à mettre après -l?
Gabriele Cirulli
48
Regardez dans / lib ou / usr / lib. Les bibliothèques sont toutes nommées lib<name>.aou lib<name>.so- c'est le "<nom>" que vous mettez après le -l. Dans ce cas, la bibliothèque mathématique est nommée libm.so, nous l'appelons donc -lm.
ams
3
Merci! Je cherche sur Google depuis 30 minutes et c'est la première référence qui dit de lier les bibliothèques après les objets
Dave Baghdanov
Vous pouvez également utiliser LD_PRELOAD pour indiquer à ld runtime linker d'inclure libm.so dans la carte mémoire et la table des symboles du processus, afin que ces symboles soient chargés et que tout fonctionne comme prévu
début
Merci d'avoir répondu. Mais quelqu'un peut-il me dire pourquoi dans le cas de codes avec quelques lignes, ça va même si je n'inclus pas -lm lors de la compilation?
MItrajyoti Kusari
24

Ajoutez -lm à vos options de lien, car pow () et floor () font partie de la bibliothèque mathématique:

gcc fib.c -o fibo -lm
Yann Droneaud
la source
9

Pour le bénéfice de quiconque lira ceci plus tard, vous devez établir un lien avec cela comme Fred l'a dit:

gcc fib.c -lm -o fibo

Un bon moyen de savoir quelle bibliothèque vous devez lier est de vérifier la page de manuel s'il en existe une. Par exemple, man powet man floorvous diront tous les deux:

Lien avec -lm.

Une explication pour lier une bibliothèque mathématique en programmation C - Liaison en C

spike.barnett
la source
8

En ce qui concerne la réponse fournie par Fuzzy:

Je devais en fait faire quelque chose de légèrement différent.

Projet -> Propriétés -> Construction C / C ++ -> Paramètres -> GCC C Linker -> Bibliothèques

Cliquez sur la petite icône verte d'ajout, tapez m et appuyez sur ok. Tout dans cette fenêtre est automatiquement appliqué à -l puisqu'il s'agit d'une bibliothèque.

Greg K
la source
6

Trouver le point où ajouter le -lm dans Eclipse-IDE est vraiment horrible, donc cela m'a pris du temps.

Si quelqu'un d'autre utilise également Edlipse, voici comment ajouter la commande:

Projet -> Propriétés -> Construction C / C ++ -> Paramètres -> GCC C Linker -> Miscelleaneous -> Linker flags: dans ce champ, ajoutez la commande -lm

Flou
la source
0

Toutes les réponses ci-dessus sont incomplètes, le problème réside ici dans l'éditeur de liens ldplutôt que dans le compilateur collect2: ld returned 1 exit status. Lorsque vous compilez votre fib.cobjet to:

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

nmrépertorie les symboles du fichier objet. Vous pouvez voir que cela a été compilé sans erreur, mais pow, flooret les printffonctions ont des références non définies, maintenant si je vais essayer de lier cela à l'exécutable:

$ 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

Im obtenir une sortie similaire que vous obtenez. Pour résoudre cela, je dois indiquer à l'éditeur de liens où chercher les références powet floor, à cette fin, j'utiliserai l' -lindicateur de l' éditeur de liens avec mlequel provient de la libm.sobibliothèque.

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

Vous pouvez maintenant voir, les fonctions pow, floorsont liées GLIBC_2.2.5.

L'ordre des paramètres est également important, à moins que votre système ne soit configuré pour utiliser des bibliothèques partagées par défaut, mon système ne l'est pas, donc lorsque j'émets:

$ 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

Remarquez l' -lmindicateur avant le fichier objet. Donc, en conclusion, ajoutez un -lmdrapeau après tous les autres indicateurs et paramètres, pour être sûr.

bladekp
la source