链接错误-gcc-lm

链接错误-gcc-lm,gcc,ubuntu,linker,ld,math.h,Gcc,Ubuntu,Linker,Ld,Math.h,嗯,我觉得我的问题有点有趣,我想了解我的Ubuntu盒子里发生了什么 我编译并链接了以下无用的代码: /*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); } 然后停下来。发生了什么事?为什么我不

嗯,我觉得我的问题有点有趣,我想了解我的Ubuntu盒子里发生了什么

我编译并链接了以下无用的代码:

/*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);
}
然后停下来。发生了什么事?为什么我不能那样编译

我还尝试了一个
sudo ldconfig-v
,但没有成功

提前谢谢


卢卡斯。

这里发生了两件不同的事情

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

(如果使用

gcc -S useless.c
再看一看生成的汇编语言列表
无用的.s
,您可以看到没有调用
sin

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

gcc -o useless useless.c -lm


链接器按顺序处理文件,跟踪每个文件的未解析符号(
sin
,由
无用的.o
引用),然后根据它们的定义解析它们。如果将
-lm
放在第一位,则在处理数学库时没有未解析的符号;当它在
无用的.o
中看到对
sin
的调用时,为时已晚。

我正要发布相同的消息,但无法理解为什么第一次成功(
sin()
),谢谢你的回答和解释!我已经重新排列了答案(它仍然有相同的信息)。
intmain()
应该是
intmain(void)
return
语句中的括号是不必要的;您可以只写
返回0。因此,在C99或更高版本中,您可以省略
返回0
gcc -S useless.c
gcc -o useless useless.c -lm
gcc useless.c -lm -o useless