The following code is throwing undefined symbol error on Linux.
$ cat rms.c
/* sqrt example */
#include <stdio.h>
#include <math.h>
int main ()
{
double param, result;
param = 1024.0;
result = sqrt (param);
printf ("sqrt(%lf) = %lf\n", param, result );
return 0;
}
$ gcc rms.c
/tmp/ccaWecFP.o(.text+0x24): In function `main':
: undefined reference to `sqrt'
collect2: ld returned 1 exit status
If I replace argument to sqrt() with (double)16 then program is compiling and executing. Why is this throwing error in first case.
This is a linker error.
The linker is missing the implementation of sqrt()
. It resides in the library libm
.
Tell GCC to add it by applying the option -lm
.
The implementation of sqrt()
is available in the math library or libm
.
You have to link your program to the math library, as:
gcc rms.c -lm
A natural question is, how am I supposed to know this? The answer is in the manpages. If I do "man sqrt", I see the following. Note that the linking instruction is provided in the synopsis.
SYNOPSIS
#include <math.h>
double sqrt(double x);
Link with -lm.
You must link with libm
gcc rms.c -lm
If you want more explanation Linking with external libraries.
Good Luck ;)
As the other answers say, you need to pass -lm
in order to link to the library containing the sqrt
symbol.
The reason it works with a constant argument is because sqrt
is allowed to be implemented as a builtin. When GCC sees a builtin function called with constant arguments, it can calculate the result at compile-time instead of emitting a call to the external function in the library.
The other answers here discuss the linking error; I'm going to add an answer about why the result is correct if you replace param
with a constant.
GCC has an optimization where it replaces functions with builtin equivalents (such as sqrt
) and constant arguments (such as 16.0
) with the results of those calculations (such as 4.0
).
This is a form of constant folding.
来源:https://stackoverflow.com/questions/15743330/sqrt-function-link-error