繁体   English   中英

在编译和链接C代码时,为什么在某些情况下不需要-lm?

[英]Why is -lm not necessary in some cases when compiling and linking C code?

我这里有一个示例文件:

#include <stdio.h>
#include <math.h>

int main(){
  printf("%f\n", log(10));
}

当我使用gcc sample.c -oa编译它时它工作得很好。 我可以使用./a运行它,它会像预期的那样产生输出2.302585

然而,当我的文件看起来像这样:

#include <stdio.h>
#include <math.h>

int main(){
  double a = 10;
  printf("%f\n", log(a));
}

它不能用gcc sample.c -oa编译。 相反,我必须使用gcc sample.c -oa -lm这样我才能明确地告诉它“链接数学”...这就是我没有真正遵循的地方,为什么我不必在第一次链接数学例? 它究竟是什么意思必须“链接数学”? 自从我使用C编译器以来已经有一段时间了,所以如果这是一个糟糕的问题,请原谅我。

检查反汇编,您可能会发现编译器在第一种情况下完全优化了对log()的调用(因此没有任何链接),但在第二种情况下则没有。 在这种特殊情况下,glibc定义:

# define M_LN10     2.30258509299404568402

例如,在math.h ,任何标准库函数都可以实现为宏,因此它可以在没有函数调用的情况下计算其中的一些内容。

根据GCC文档 ,可能不会调用数学库函数,某些内联函数已定义,在某些情况下可能会被调用。

... GNU C库为许多常用的数学函数提供了优化。 当使用GNU CC并且用户激活优化器时,会定义几个新的内联函数和宏。 这些新函数和宏与库函数具有相同的名称,因此使用它们而不是后者。 在内联函数的情况下,编译器将决定使用它们是否合理,并且此决定通常是正确的。

这意味着不需要调用库函数 ,并且可以显着提高生成代码的速度。 缺点是代码大小会增加,并且增加并不总是可以忽略不计。

由于某些原因,即使使用-O0,gcc也会优化log(const)。 所以在第一种情况下没有log()调用。 检查装配以验证:

gcc sample.c -S

例如,clang并没有在O0上优化它。 但是在O2中,gcc在两种情况下都优化了呼叫。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM