web-dev-qa-db-fra.com

Référence non définie à `sin`

J'ai le code suivant (réduit au strict minimum 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;
}

Lors de la compilation avec gcc test.c Je reçois 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 à partir de la fonction main, et ceux-ci fonctionnent parfaitement. Je dois faire quelque chose de manifestement faux, mais qu'est-ce que c'est?

90
robintw

Vous avez compilé votre code avec des références au fichier d'en-tête math.h correct, mais lorsque vous avez tenté de le lier, vous avez oublié l'option permettant d'inclure la bibliothèque mathématique. Par conséquent, vous pouvez compiler vos fichiers objet .o, mais pas créer votre exécutable.

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

Dans le commentaire , linuxD demande:

Pourquoi pour sin() dans <math.h>, Avons-nous besoin de l'option -lm De manière explicite; 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". Cet historique de cette norme est intéressant et porte plusieurs noms (IEEE Standard 1003.1, Guide de la portabilité X/Open, POSIX, Spec 1170).

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

Bibliothèque Standard C

La bibliothèque Standard C est automatiquement recherchée par cc pour résoudre les références externes. Cette bibliothèque prend en charge toutes les interfaces du système de base, telles que définies dans le volume 1, à l'exception des 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ée pour effectuer une recherche dans cette bibliothèque.

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

  1. Les guerres UNIX ont entraîné une divergence croissante par rapport à l'offre initiale d'UN & AT & T.
  2. Le nombre de plates-formes UNIX a ajouté des difficultés pour développer des logiciels pour le système d'exploitation.
  3. Une tentative de définition du plus petit dénominateur commun pour les développeurs de logiciels a été lancée, appelée 1988 POSIX .
  4. Les développeurs de logiciels ont programmé conformément à la norme POSIX pour fournir leurs logiciels sur des "systèmes compatibles POSIX" afin d'atteindre davantage de plates-formes.
  5. Les clients UNIX ont demandé aux systèmes UNIX "compatibles POSIX" de faire fonctionner le logiciel.

Les pressions qui ont influencé la décision de placer -lm Dans une bibliothèque différente ont probablement été incluses, mais ne se limitent pas à:

  1. Cela semble être un bon moyen de réduire la taille de libc, car de nombreuses applications n'utilisent pas les fonctions incorporées dans la bibliothèque mathématique.
  2. Il offre une flexibilité dans la mise en œuvre des bibliothèques mathématiques, certaines bibliothèques reposant sur des tables de recherche incorporées plus volumineuses, tandis que d'autres peuvent compter sur des tables de consultation plus petites (solutions informatiques).
  3. Pour les applications véritablement contraintes en taille, cela permet des réimplémentations de la bibliothèque mathématique d'une manière non standard (comme extraire simplement sin() et l'insérer dans une bibliothèque construite sur mesure).

Dans tous les cas, cela fait maintenant partie de la norme de ne pas être automatiquement inclus dans le langage C, et c'est pourquoi vous devez ajouter -lm.

110
Edwin Buck

J'ai le problème quand même 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 fonctionnait pas si vous spécifiez d'abord -lm. L'ordre compte:

gcc mtest.c -o mtest.o -lm

Juste lier sans problèmes

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

61
Anyeos

Vous devez créer un lien avec la bibliothèque mathématique, libm:

$ gcc -Wall foo.c -o foo -lm 
38
Paul R

J'ai eu le même problème, qui est parti après avoir répertorié ma dernière bibliothèque: gcc prog.c -lm

10
blackappy