为什么仅在将变量传递给“ math.h”函数时才明确使用“ -lm”?

时间:2019-03-04 07:50:08

标签: c math gcc linker compiler-optimization

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

为什么仅在将变量用作参数而不是常量时,为什么必须使用-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

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

以下是我尝试过的代码段:

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

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

1 个答案:

答案 0 :(得分:4)

这很简单。当您传递常量时,许多编译器会在不调用math.h函数的情况下对它进行评估(在这样一个琐碎的示例中,当结果不是浮点数不准确且实现差异容易产生时)。

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

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