Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to
sin. It sees that the argument is a constant expression, so it replaces thesin(...)call with the result of the expression, and the math library isn't needed. It will work just as well without the-lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)(If you compile with
and take a look at
useless.s, the generated assembly language listing, you can see that there's no call tosin.)For the second example, you do need the
-lmoption -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:or
The linker processes files in order, keeping track of unresolved symbols for each one (
sin, referred to byuseless.o), and then resolving them as it sees their definitions. If you put the-lmfirst, there are no unresolved symbols when it processes the math library; by the time it sees the call tosininuseless.o, it's too late.