c - 为什么仅在将变量传递给“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;
}
解决方案
这很简单。当您传递常量时,许多编译器将评估它(在这样一个简单的例子中,当结果不是浮点不准确和易于实现差异时)编译时间而不调用 math.h 函数。
即使您不传递常量值并在没有数学错误检查和快速数学的情况下对其进行编译,编译器也会生成直接浮点机器代码指令,而无需调用库指令
在询问之前检查生成的代码,例如使用 godbolt.org,通常它会回答你所有的问题
推荐阅读
- rally - Java 中的 RallyApi - 尝试返回功能的项目层次结构
- node.js - 使用节点运行 js 文件给了我一个“HTMLDivElement”未定义。我需要导入它,还是特定于 Node 之外的浏览器?
- c++ - 谷歌测试夹具作为班级成员
- c# - 在完成当前异步方法(wpf)之前允许所有正在运行的任务完成的通用方法?
- javascript - setState 是否需要一些时间来执行?
- r - 如何找到在分类变量中具有两个组之一的连续变量的 SD 和均值
- java - 如何使用 mockito 模拟泛型方法?
- google-maps - 地理编码 API 发送不一致的结果
- javascript - 动态加载不在 type="module" 的脚本标签中的模块?
- sql-server - 使用 T-SQL 查找与 SSRS 报告关联的存储过程