At page 14 of the book "Introduction to GCC" by Brian Gough, the author wants to show a linker error due to not supplying gcc with the libm
library, where the code for the function sqrt
resides:
$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function ‘main’:
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference to ‘sqrt’
The file calc.c
(where the functionsqrt
is invoked) is this:
#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;
}
This book is from 2003. On my current Ubuntu Linux 18, I can't reproduce the link error: it links and works, printing the correct result:
$ ./calc
1.414214
I found with ldd calc
that the libm.so
shared library is not invoked at runtime. Nor of course is the static library libm.a
involved here.
So how does gcc deal with the function sqrt
? I found that in this case it uses the sqrt
GCC built-in function.
Its code gets inserted in the calc.o
object file at compile time. So no "undefined reference" error.
First question: this the whole story or am I missing something?
Second question: why did this behavior regarding the built-in functions of GCC change so much between 2003 (when the book was written) and now? (Practically invalidating the whole example, it seems to me)
Third question: why does the author make his examples (e.g.$ gcc -Wall calc.c -lm -o cal
) implying that the static library libc.a
will be used, when in reality in Linux that syntax invokes the dynamic library libm.so
? Is this specific to Linux and not to GNU GCC? What am I mising?
I think this is due to optimization of a constant value. Modern GCC can compute exact value of sqrt (2.0)
. If you force it not to use the built-ins with -fno-builtin
, it will still fail to link. Also, if you change the code a little bit so that the argument to sqrt()
is not literal, it will fail to link:
#include <math.h>
#include <stdio.h>
double t = 2.0;
int main (void)
{
double x = sqrt (t);
printf ("The square root of 2.0 is %f\n", x);
return 0;
}
This produces link error:
> gcc -o test test.c
/usr/bin/ld: /tmp/ccLjHnQx.o: in function `main':
test.c:(.text+0x11): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Regarding your 3rd question, -lm
does not imply static library, AFAIK.