I am reading a book titled "An Introduction to GCC" and would like some clarification. The book indicates that the code below will cause an error but when I compile, it builds and runs perfectly:
#include <math.h>
#include <stdio.h>
int main (void) {
double x = sqrt (2.0);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}
I quote from the book "Trying to create an executable from this source file alone causes the compiler to give an error at the link stage:"
$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function `main':
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference
to `sqrt'
The solution that the book gives is that you are supposed to include the path to the math library ‘libm.a’ as follows:
$ gcc -Wall calc.c /usr/lib/libm.a -o calc
It would be very inconvenient to have to specify the paths to built in libraries that we use in our programs. I can understand the reason for adding the path to my own custom libraries, but libm.a is built into gcc. And although the book is quite old (published in 2004), what has changed with more modern versions of gcc, so that we do not need to include the path to libm.a?
* UPDATE *
I noticed that the answer given by taskinoor demonstrates updated code that requires that I use the -lm flag if the value passed to sqrt() is not known at compile time.
I learned C/C++ using VS but my goal now is to learn and use gcc. I have Visual Studio 2013 and the VS compiler/linker does not seem so picky. For example, I am able to compile just about any simple program without having to specify mysterious compiler flags.
I am learning on gcc version 5.4 that comes with KUBUNTU 16.04.1
sqrt (2.0);
Modern GCC is well capable to determine that you are trying to find square root of a constant and thus it is able to calculate that in compile time. Your object code does not contain an actual call to sqrt
.
If you use a variable which is input via scanf
at run then it won't link without libm
.
int main() {
double x;
scanf("%lf", &x);
printf("%lf\n", sqrt(x));
return 0;
}
Without libm
gcc 4.8.4 on Ubuntu 14.04 this results:
/tmp/ccVO2fRY.o: In function `main':
sqrt.c:(.text+0x2c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
But if I put a constant instead of x
like your example then it links fine without libm
.
P.S: I don't know the exact version since when GCC is able to do this. Hopefully someone else can point to that.
I've noticed that on some operating systems, common libraries are available without explicit linking. In particular, I've often taken a working C project originally developed on my Mac, and the project would not compile on Linux until I explicitly linked against the libraries I used (like libm).
Of course, this is typically for dynamic rather than static linking...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With