2009-11-10 15 views
6

ho creato un piccolo programma, come segue:sqrt da math.h provoca errore di linker "riferimento indefinito a sqrt" solo quando l'argomento non è una costante

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

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

Quando provo a compilare questo con il seguente comando, ottengo un errore del compilatore.

gcc -Wall calc.c -o calc 

rendimenti:

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

Se io sostituire la variabile nella chiamata a sqrt (xx) con una costante come sqrt (10.2), si compila bene. O, se collego esplicitamente come il seguente:

gcc -Wall -lm calc.c -o calc 

Funziona anche bene. Qualcuno può dirmi che cosa sta causando questo? Sono un programmatore C da molto tempo (e ho scritto piccoli programmi simili usando math.h) e non ho mai visto nulla di simile.

La mia versione di gcc segue:

$ 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. 
$ 
+0

Ha ancora bisogno di '-lm' se si specifica' --std = c99'? –

+0

Sì. Strano. Ho anche provato a usare -ansi per lo stesso effetto. No-go senza -lm – alesplin

+4

È un'interessante funzionalità di gcc che è necessario collegare in modo esplicito la libreria matematica, che cattura tutti prima volta. Che il compilatore possa tranquillamente sostituire sqrt (10.2) per te aggiunge solo divertimento! –

risposta

16

Se si guarda l'output del compilatore nel caso in cui si è utilizzato sqrt(10.2), scommetto che si vede che una chiamata a sqrt() non è in realtà fatta .

Ciò accade perché GCC riconosce diverse funzioni che può trattare appositamente. Questo gli dà la possibilità di fare certe ottimizzazioni, in questo caso Constant folding. Tali funzioni speciali sono chiamate Built-ins.

Nel caso in cui sia necessario collegarsi alla libreria matematica (poiché la si chiama con una variabile), è necessario collegarlo in modo esplicito. Alcuni sistemi operativi/compilatori lo fanno per te, motivo per cui potresti non averlo notato in passato.

+2

+1 Molti sistemi automaticamente collegamento alla biblioteca matematica per te. Alcuni no. Il tuo no. –

+11

Penso che quello che sta cercando di dire è che se si prende lo sqrt di una costante, il risultato è anche una costante, quindi il compilatore lo fa per te in fase di compilazione, senza lasciare chiamate a sqrt nel codice, quindi non lo fai t necessario collegarsi a libm (-lm) ​​al momento del collegamento. –

+0

Southern Hospitality ha ragione. –

Problemi correlati