快速数学导致对"__pow_finite"的未定义引用

fast-math cause undefined reference to `__pow_finite'

本文关键字:pow finite 引用 未定义      更新时间:2023-10-16

在 ubuntu 20.04 上,当我使用 clang-8 或 clang-9(clang 版本 9.0.1-12(编译包含对 libm 引用的简单代码时,它会失败并显示错误"未定义对__pow_finite的引用">

#include <math.h>
int main()
{
double x=1, y=1;
x = pow(x,y);
}
clang-9 -lm test.c -ffast-math
/usr/bin/ld: /tmp/test-9b1a45.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'
readelf -Ws /lib/x86_64-linux-gnu/libm.so.6| grep pow_finite
626: 000000000002ed90    65 IFUNC   GLOBAL DEFAULT   17 __pow_finite@GLIBC_2.15

海湾合作委员会很好。知道这里出了什么问题吗?

C ++也有同样的问题:

#include <cmath>
int main()
{
double x=1, y=1;
x = pow(x,y);
}

编辑

我实际上使用了-lm,我只是忘了输入文本。如果我不添加它,那就是另一个错误。

$ clang-9 test.c
/usr/bin/ld: /tmp/test-3389a6.o: in function `main':
test.c:(.text+0x25): undefined reference to `pow'
$ gcc test.c
/usr/bin/ld: /tmp/cc21n4wb.o: in function `main':
test.c:(.text+0x39): undefined reference to `pow'

F31没有这个问题。 戈博尔特也很好。一定是系统出了问题或特定的颠覆。

到目前为止,顺序无关紧要,所以我认为它不是 gcc 不会正确包含 math.h:

clang-9 test.c -ffast-math -lm
/usr/bin/ld: /tmp/test-6dfc29.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'
clang-9 -ffast-math test.c -lm
/usr/bin/ld: /tmp/test-6754bc.o: in function `main':
test.c:(.text+0x2a): undefined reference to `__pow_finite'

将 ld 更改为 collect2 有同样的问题,所以它不应该是 ld 的问题。

clang-9 -v -fuse-ld=/usr/lib/gcc/x86_64-linux-gnu/9/collect2 test.c -ffast-math -lm

更新

它似乎与libc更新有关。不再有math-finite.h,因此当-ffast-math生成__*finite时,它将失败。Clang必须改变其行为。

TL;TR:这是 clang 中的一个错误,在 clang-10 中修复。如果有人有同样的问题,请使用最新的 GCC 或 Clang 版本或设置-fno-finite-math-only

造成这种情况的根本原因是 clang 错误地在 libm 中调用了一些非 API 函数:

它们只是 ABI(通过使用 -ffinite-math-only 或 暗示它的选项,这导致标头使用"ASM"重定向 调用某些 libm 函数(,而不是 API。这一变化意味着ABI已经 转换为兼容符号(仅适用于现有二进制文件,不适用于 任何新链接的,根本不包含在静态 libm 中,不包含在 未来 glibc 端口(如 RV32(的共享 libm(,所以,是的,无论如何 工具生成对这些函数的直接调用(而不仅仅是 在标题中函数声明的"ASM"注释之后(, 他们需要停止这样做。

错误已经在这里被跟踪并使用 PR 修复了很长时间 clang-10。

有关删除这些内容的原因的更多上下文,请参阅提案:删除或减少math-finite.h:

对于此文件中的某些函数; pow, powf, log, logf, log2, log2f, exp、expf、exp2 和 exp2f;默认实现已得到改进 处理特殊情况,*_finite 名称只是 正常名称,因此 ASM 属性没有完成任何操作。

编译时添加头文件,clang -L/home/xiaokuan/lib/glibc-2.32-install/lib -I/home/xiaokuan/lib/glibc-2.32-install/include -lm -ffast-math a.c