链接错误 – gcc -lm

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

我用gcc -lm -o useless useless.c编译并链接了gcc -lm -o useless useless.c下面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没有成功。

提前致谢!

卢卡斯。

这里有两件不同的事情。

对于第一个例子,编译器不会产生对sin的调用。 它认为参数是一个常量表达式,所以它用表达式的结果替换了sin(...)调用,并且不需要数学库。 没有-lm就可以工作。 (但是你不应该指望这一点;当编译器执行这种优化时,并不总是很明显。)

(如果你编译

 gcc -S useless.c 

并看看useless.s ,生成的汇编语言列表,你可以看到没有sin的呼声。)

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

 gcc -o useless useless.c -lm 

要么

 gcc useless.c -lm -o useless 

链接器按顺序处理文件,跟踪每个文件的未解析符号( sin ,由useless.o ),然后在查看它们的定义时解析它们。 如果你先把-lm放进去,在处理数学库的时候就没有未解决的符号; 当它看到useless.o sin时,它已经太迟了。