Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
370 views
in Technique[技术] by (71.8m points)

c - sqrt from math.h causes linker error "undefined reference to sqrt" only when the argument is not a constant

I created a small program, as follows:

  #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
", xx,tmp);
      sleep(1);
      xx = 0;
    }

    return 0;
 }

When I try to compile this with the following command, I get a compiler error.

gcc -Wall calc.c -o calc

returns:

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

If I replace the variable in the call to sqrt(xx) with a constant like sqrt(10.2), it compiles just fine. Or, if I explicitly link like the following:

gcc -Wall -lm calc.c -o calc

It also works just fine. Can anyone tell me what's causing this? I've been a C programmer for a long time (and I've written similar small programs using math.h) and I have never seen anything like this.

My version of gcc follows:

$ 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.
$
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you look at the output of the compiler in the case where you used sqrt(10.2), I'll bet you see that a call to sqrt() isn't actually made.

This happens because GCC recognizes several functions that it can treat specially. This gives it the ability to do certain optimizations, in this case Constant folding. Such special functions are called Built-ins.

In the case where it must link to the math library (because you're calling it with a variable), you need to link it explicitly. Some operating systems/compilers do it for you, which is why you might not have noticed in the past.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...