首页 > 解决方案 > 为什么仅在将变量传递给“math.h”函数时才显式使用“-lm”?

问题描述

首先,我读过这篇文章Why do you need an explicit `-lm` compiler option & this gcc: why is the -lm flag required 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

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

以下是我尝试的片段:

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

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

标签: cmathgcclinkercompiler-optimization

解决方案


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

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

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


推荐阅读