【问题标题】:Why is '-lm' used explicitly only when passing variables to 'math.h' functions?为什么仅在将变量传递给“math.h”函数时才显式使用“-lm”?
【发布时间】:2019-03-04 07:50:07
【问题描述】:

首先,我读过这篇文章Why do you need an explicit `-lm` compiler option 和这篇gcc: why is the -lm flag needed to link the math library?。我想知道为什么它不会发生在常量的情况下(当我说常量时,我​​的意思是随机浮点数/双精度数)?如果你感到困惑,称之为浮点文字。

为什么我们必须使用-lm 告诉链接器仅在使用变量作为参数而不是常量时才使用math.h 函数?如果我使用sqrt(N)(N 是某个数字),它编译得很好,没有任何错误,但是当我传递一些变量时,比如说sqrt(var),它不会。它说:

/usr/bin/ld: /tmp/cc5P9o72.o: in function `main':
sq.c:(.text+0x1b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

当我使用同一个库中的同一个函数时,它应该一直表现相同(我想是这样,但我当然错了)。它的变量或常数。我首先认为它是某种编译器优化(如果它每次都是相同的值,为什么不通过其他方式编译时计算它,即不使用库,因为它不起作用)但即使我通过它也不起作用一些从头到尾都有固定值的变量。所以,我错了。这里到底发生了什么?

下面是我试过的sn-p:

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

int main () {
    float a=9;
    printf("%f",sqrt(a));
    return 0;
}

【问题讨论】:

  • 因为默认情况下链接器不与数学库链接。这不是一个问题。
  • 数学函数很昂贵,传统上不常用。因此,为了节省空间,它们被放入了自己的库中。
  • 我在链接的帖子上读到了这一点。问题是为什么只使用变量?
  • C 原生支持浮点常量和变量。此外,新编译器不再需要 -lm 和数学函数。
  • 那么为什么它不适用于变量中的整数/浮点数

标签: c math gcc linker compiler-optimization


【解决方案1】:

这很简单。当您传递常量时,许多编译器将对其进行评估(在这样一个简单的示例中,当结果不是浮点不准确和易于实现差异时)编译时间而不调用 math.h 函数。

即使您不传递常量值并在没有数学错误检查和快速数学的情况下编译它,编译器也会生成直接浮点机器代码指令而不调用库指令

在询问之前检查生成的代码,例如使用 godbolt.org,通常它会回答你所有的问题

【讨论】:

  • 不是优化。
  • @Jean-FrançoisFabre 仔细阅读了我的回答。 琐碎和数字9是关键点。 sqrt(9) 的结果始终相同,浮点实现差异无关紧要
  • @P__J__ 你的答案是最好的。所以,我有点满意,但是当我使用 var=9 时,它总是具有与 just 9 相同的值。为什么不一样?
  • 我已经在我的回答中解释过了
猜你喜欢
  • 2012-03-03
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
相关资源
最近更新 更多