链接错误 - gcc -lm

时间:2012-01-22 00:24:33

标签: gcc ubuntu linker ld math.h

好吧,我认为我的问题有点儿有趣,我想了解我的Ubuntu盒子里发生了什么。

我编译并链接了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);
}

到目前为止一切顺利。但是当我改变这个时:

/*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);
}

我尝试使用相同的命令行编译,gcc响应:

/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status

然后停下来。怎么了?为什么我不能这样编译?

我还尝试了sudo ldconfig -v但没有成功。

提前致谢!

卢卡斯。

1 个答案:

答案 0 :(得分:12)

这里有两件不同的事情。

对于第一个示例,编译器不会生成对sin的调用。它看到参数是一个常量表达式,因此它将sin(...)调用替换为表达式的结果,并且不需要数学库。没有-lm,它也可以正常工作。 (但是你不应该指望它;当编译器执行这种优化时它并不总是显而易见的,而且它不会。)

(如果使用

进行编译
gcc -S useless.c

并查看useless.s生成的汇编语言列表,您可以看到没有对sin的调用。)

对于第二个示例,您确实需要-lm选项 - 但它需要位于命令行的末尾,或者至少需要在需要它的文件(useless.c)之后:

gcc -o useless useless.c -lm

gcc useless.c -lm -o useless

链接器按顺序处理文件,跟踪每个文件的未解析符号(sin引用的useless.o),然后在看到它们的定义时解析它们。如果先放置-lm,则在处理数学库时没有未解析的符号;当它在sin中看到useless.o的来电时,为时已晚。