链接错误 - gcc -lm [英] Linking error - gcc -lm

查看:38
本文介绍了链接错误 - 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆