Search code examples
gccubuntulinkerldmath.h

A linking error related to 'gcc' and '-lm'


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.


Solution

  • 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 the sin(...) 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

    gcc -S useless.c
    

    and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)

    For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:

    gcc -o useless useless.c -lm
    

    or

    gcc useless.c -lm -o useless
    

    The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.