Référence indéfinie à ' sin ' [dupliquer]

Cette question a déjà une réponse ici:

J'ai le code suivant (réduit aux bases bues pour cette question):

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

double f1(double x)
{
    double res = sin(x);
    return 0;
}

/* The main function */
int main(void)
{
    return 0;
}

En le compilant avec gcc test.c j'obtiens l'erreur suivante, et je ne peux pas comprendre pourquoi:

/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status

Cependant, j'ai écrit divers programmes de test qui appellent sin depuis la fonction main, et ceux-ci fonctionnent parfaitement. Je dois faire quelque chose de manifestement mal ici - mais quel est-il?

86
demandé sur alk 2011-02-15 18:09:27

4 réponses

Vous avez compilé votre code avec des références aux mathématiques correctes.h fichier d'en-tête, mais lorsque vous avez tenté de le lier, vous avez oublié l'option d'inclure la bibliothèque mathématique. Comme un résultat, vous pouvez compiler votre .o fichiers objet, mais pas créer votre exécutable.

Comme Paul l'a déjà mentionné, ajoutez "-lm " pour créer un lien avec la bibliothèque mathématique à l'étape où vous essayez de générer votre exécutable.

Dans le commentaire, linuxD demande:

Pourquoi pour sin() dans <math.h>, avons-nous besoin de -lm option explicitement; mais, pas pour printf() dans <stdio.h>?

Parce que ces deux fonctions sont implémentées dans le cadre de la "spécification UNIX unique". Cette histoire de cette norme est intéressante et est connue sous de nombreux noms (IEEE Std 1003.1, X / Open Portability Guide, POSIX, Spec 1170).

Cette norme, sépare spécifiquement les routines" bibliothèque C Standard "des routines" bibliothèque mathématique C Standard " (page 277). Le passage pertinent est copié ci-dessous:

Bibliothèque C Standard

La bibliothèque C Standard est automatiquement recherchée par cc pour résoudre les références externes. Cette bibliothèque prend en charge tous les interfaces du système de Base, telles que définies dans le Volume 1, à l'exception Routines Mathématiques.

Bibliothèque Mathématique Standard C

Cette bibliothèque prend en charge les routines mathématiques du système de Base, telles que définies dans le Volume 1. L'option cc -lm est utilisé pour rechercher cette bibliothèque.

Le raisonnement derrière cette séparation a été influencé par un certain nombre de facteurs:

  1. les guerres UNIX ont conduit à une divergence croissante par rapport à L'offre originale D'AT&T UNIX.
  2. le nombre de plates-formes UNIX a ajouté des difficultés dans le développement de logiciels pour le système d'exploitation.
  3. une tentative de définir le plus petit dénominateur commun pour les développeurs de logiciels a été lancée, appelé 1988 POSIX .
  4. les développeurs de logiciels programmés par rapport à la norme POSIX pour fournir leurs logiciels sur des "systèmes compatibles POSIX" afin d'atteindre plus de plates-formes.
  5. les clients UNIX ont exigé des systèmes UNIX "compatibles POSIX" pour exécuter le logiciel.

Les pressions qui ont alimenté la décision de mettre -lm dans une bibliothèque différente probablement inclus, mais ne sont pas limités à:

  1. cela semble être un bon moyen de réduire la taille de la libc, autant d'applications n'utilisez pas de fonctions intégrées dans la bibliothèque mathématique.
  2. Il offre une flexibilité dans l'implémentation des bibliothèques mathématiques, où certaines bibliothèques mathématiques s'appuient sur des tables de recherche intégrées plus grandes tandis que d'autres peuvent s'appuyer sur des tables de recherche plus petites (solutions informatiques).
  3. pour les applications vraiment contraintes de taille, il permet des réimplémentations de la bibliothèque mathématique d'une manière non standard (comme sortir juste sin() et le mettre dans une bibliothèque personnalisée.

En tout cas, il fait maintenant partie de la norme ne doit pas être automatiquement incluse dans le langage C, et c'est pourquoi vous devez ajouter -lm.

104
répondu Edwin Buck 2017-08-26 19:59:02

J'ai le problème de toute façon avec-LM ajouté

gcc -Wall -lm mtest.c -o mtest.o
mtest.c: In function 'f1':
mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable]
/tmp/cc925Nmf.o: In function `f1':
mtest.c:(.text+0x19): undefined reference to `sin'
collect2: ld returned 1 exit status

J'ai découvert récemment que cela ne fonctionne pas si vous spécifiez d'abord-lm. L'ordre compte:

gcc mtest.c -o mtest.o -lm

Juste lien sans problèmes

Vous devez donc spécifier les bibliothèques après.

60
répondu Anyeos 2012-08-28 18:08:14

Vous devez lier avec la bibliothèque mathématique, libm:

$ gcc -Wall foo.c -o foo -lm 
36
répondu Paul R 2013-11-17 23:18:30

J'ai eu le même problème, qui est parti après avoir listé Ma bibliothèque en dernier: gcc prog.c-lm

9
répondu blackappy 2012-01-13 08:19:45