Luc*_*sBr 3 ubuntu linker gcc math.h ld
好吧,我认为我的问题有点有趣,我想了解我的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);
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是当我改变这个:
/*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);
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用相同的命令行编译,gcc响应:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
然后停下来.怎么了?为什么我不能这样编译?
我也尝试了一次sudo ldconfig -v
没有成功.
提前致谢!
卢卡斯.
Kei*_*son 12
这里有两件不同的事情.
对于第一个示例,编译器不会生成对的调用sin
.它看到参数是一个常量表达式,因此它用sin(...)
表达式的结果替换调用,并且不需要数学库.如果没有它,它也可以正常工作-lm
.(但是你不应该指望它;当编译器执行这种优化时它并不总是显而易见的.)
(如果你用.编译
gcc -S useless.c
Run Code Online (Sandbox Code Playgroud)
并看一下useless.s
,生成的汇编语言列表,你可以看到没有调用sin
.)
对于第二个示例,您确实需要-lm
选项 - 但它需要位于命令行的末尾,或者至少useless.c
需要在需要它的文件()之后:
gcc -o useless useless.c -lm
Run Code Online (Sandbox Code Playgroud)
要么
gcc useless.c -lm -o useless
Run Code Online (Sandbox Code Playgroud)
链接器按顺序处理文件,跟踪每个文件的未解析符号(sin
,引用useless.o
),然后在看到它们的定义时解析它们.如果放第-lm
一个,则在处理数学库时没有未解析的符号; 当它看到来电sin
时useless.o
,已经太晚了.
归档时间: |
|
查看次数: |
3569 次 |
最近记录: |