好吧,我认为我的问题有点有趣,我想了解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
,但没有成功。提前致谢!
卢卡斯
最佳答案
这里有两种不同的情况。
对于第一个示例,编译器不会生成对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
的调用时,为时已晚。关于gcc - 链接错误-gcc -lm,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8957967/