链接错误 - gcc -lm [英] Linking error - gcc -lm
问题描述
好吧,我认为我的问题有点有趣,我想了解我的 Ubuntu 机器中发生了什么.
Well, I think my problem is a little bit interesting and I want to understand what's happening in my Ubuntu box.
我编译并使用 gcc -lm -o useless useless.c
链接了以下无用的代码:
I compiled and linked with gcc -lm -o useless useless.c
the following useless piece of code:
/*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);
}
到目前为止一切顺利.但是当我改成这样:
So far so good. But when I change to this:
/*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 响应:
And I try to compile using same command line, gcc responses:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
然后停下来.怎么了?为什么我不能这样编译?
And stops. What is happening? Why I can't compile that way?
我也尝试了 sudo ldconfig -v
没有成功.
I tried also a sudo ldconfig -v
without success.
提前致谢!
卢卡斯.
推荐答案
这里有两件不同的事情.
There are two different things going on here.
对于第一个示例,编译器不会生成对 sin
的调用.它看到参数是一个常量表达式,所以它用表达式的结果替换了 sin(...)
调用,并且不需要数学库.如果没有 -lm
,它也能正常工作.(但您不应该指望这一点;编译器何时执行此类优化以及何时不执行并不总是很明显.)
For the first example, the compiler doesn't generate a call to sin
. It sees that the argument is a constant expression, so it replaces the sin(...)
call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm
. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(如果你用
gcc -S useless.c
并查看生成的汇编语言列表useless.s
,您可以看到没有调用sin
.)
and take a look at useless.s
, the generated assembly language listing, you can see that there's no call to sin
.)
对于第二个示例,您确实需要 -lm
选项 -- 但它需要在命令行的末尾,或者至少在文件 (useless.c
) 需要它:
For the second example, you do need the -lm
option -- but it needs to be at the end of the command line, or at least after the file (useless.c
) that needs it:
gcc -o useless useless.c -lm
或
gcc useless.c -lm -o useless
链接器按顺序处理文件,跟踪每个文件的未解析符号(sin
,由 useless.o
引用),然后按照它所看到的进行解析他们的定义.如果把-lm
放在最前面,它在处理数学库时就没有未解析的符号;当它在 useless.o
中看到对 sin
的调用时,已经太晚了.
The linker processes files in order, keeping track of unresolved symbols for each one (sin
, referred to by useless.o
), and then resolving them as it sees their definitions. If you put the -lm
first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin
in useless.o
, it's too late.
这篇关于链接错误 - gcc -lm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!