sqrt de math.h provoque l’erreur de l’éditeur de liens «référence indéfinie à sqrt» uniquement lorsque l’argument n’est pas une constante

J’ai créé un petit programme, comme suit:

#include  #include  #include  int main(int argc, char *argv[]) { int i; double tmp; double xx; for(i = 1; i <= 30; i++) { xx = (double) i + 0.01; tmp = sqrt(xx); printf("the square root of %0.4f is %0.4f\n", xx,tmp); sleep(1); xx = 0; } return 0; } 

Lorsque j’essaie de comstackr cela avec la commande suivante, j’obtiens une erreur de compilation.

 gcc -Wall calc.c -o calc 

résultats:

 /tmp/ccavWTUB.o: In function `main': calc.c:(.text+0x4f): undefined reference to `sqrt' collect2: ld returned 1 exit status 

Si je remplace la variable dans l’appel à sqrt (xx) par une constante comme sqrt (10.2), la compilation est parfaite. Ou, si je lie explicitement comme suit:

 gcc -Wall -lm calc.c -o calc 

Cela fonctionne aussi très bien. Quelqu’un peut-il me dire ce qui cause cela? Je suis programmeur C depuis longtemps (et j’ai écrit de petits programmes similaires utilisant math.h) et je n’ai jamais rien vu de tel.

Ma version de gcc suit:

 $ gcc --version gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ 

Si vous regardez la sortie du compilateur dans le cas où vous avez utilisé sqrt(10.2) , je parie que vous voyez qu’un appel à sqrt() n’est pas réellement effectué.

Cela se produit car GCC reconnaît plusieurs fonctions qu’il peut traiter spécialement. Cela lui donne la possibilité de faire certaines optimisations, dans ce cas, le pliage constant . Ces fonctions spéciales s’appellent les Built-ins .

Dans le cas où il doit être lié à la bibliothèque mathématique (parce que vous l’appelez avec une variable), vous devez le lier explicitement. Certains systèmes d’exploitation / compilateurs le font pour vous, raison pour laquelle vous ne l’auriez peut-être pas remarqué par le passé.