Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么使用libgcc.a中的sqrtf函数会导致link双精度函数?_C_Linker_Math.h - Fatal编程技术网

为什么使用libgcc.a中的sqrtf函数会导致link双精度函数?

为什么使用libgcc.a中的sqrtf函数会导致link双精度函数?,c,linker,math.h,C,Linker,Math.h,我在项目中链接libgcc.a时遇到问题。我需要使用sqrtf和log10f,所以我在makefile中添加了libgcc.a,添加了链接器标志“-lm”,math.h作为模块中的include,一切都编译得很好,但我认为有些地方出了问题。当我更深入地研究mapfile时,只需使用sqrtf就可以实现双精度浮点处理的链接功能,例如: __阿比·达德,阿比·d2f,阿比·迪夫 还有更多。我真的不知道为什么sqrtf或log10f的单精度实现,特别是当FPU打开时,链接双精度函数。我查看了反汇编,但

我在项目中链接libgcc.a时遇到问题。我需要使用sqrtf和log10f,所以我在makefile中添加了libgcc.a,添加了链接器标志“-lm”,math.h作为模块中的include,一切都编译得很好,但我认为有些地方出了问题。当我更深入地研究mapfile时,只需使用sqrtf就可以实现双精度浮点处理的链接功能,例如:

__阿比·达德,阿比·d2f,阿比·迪夫

还有更多。我真的不知道为什么sqrtf或log10f的单精度实现,特别是当FPU打开时,链接双精度函数。我查看了反汇编,但在代码中没有找到此函数的用法。只有在图书馆里,我才发现了这些事件

我的工具链是:arm none eabi版本6-2017-q2 Cortex-M4F,连接器中启用FPU硬件


有人知道为什么会这样吗?在这种情况下,代码大小对我来说非常重要。提前感谢您的帮助。

您需要为ARM硬浮动(通常为“armhf”/“ARM-*-eabihf”ABI,尽管您仍然可以使用普通eabi,但需要使用VFP指令,即启用gcc的“softfp”模式)目标构建的标准库(libc+libm)版本。否则,您在编译时配置硬浮点支持这一简单事实不会改变您的libc/libm包含编译为引用软浮点libgcc函数的代码这一事实。

使用gcc多目标-我最熟悉的gcc工具链可以做到这一点。您需要为编译器和链接器指定正确的命令行选项

stm32f303示例

arm-none-eabi-gcc  -fno-math-errno -mcpu=cortex-m4 -mthumb -mfloat-abi=hard  -fsingle-precision-constant -mfpu=fpv4-sp-d16  -specs=nosys.specs -specs=nano.specs 
-fno math errno-不进行检查,未设置errno,将sqrtf编译为单个fpu指令 -fssingle precision constant-当我主要使用浮点时,我更喜欢这个选项,不在浮点常量的末尾写入
f
。 -mfpu=fpv4-sp-d16您的FPU(实际上是我的F303)

其余的我想是显而易见的。 该工具链应与多个FPU和内核的库一起提供,链接器将选择正确的工具链。这是一种懒惰但有效的方法

float f;
...
printf("%f", sqrtf(f));
编译成

 80028fa:   eddd 7a05   vldr    s15, [sp, #20]
 80028fe:   eeb1 7ae7   vsqrt.f32   s14, s15

如果您想从(几乎有时)最新的gcc版本中获益,请访问我的朋友网站并构建/下载他的工具链

,中间步骤可以使用比输入/输出更高的精度。如果库实现对您来说非常繁重,您可以从源代码编译
sqrt
的任何其他开源实现,或者只编写自己的实现。另一方面,该函数具有双精度(除非您使用的是非标准标题)。
libm
libgcc
不同。后者通常是自动链接的,即使没有链接标准库(IIRC,有一个选项禁止链接两者)。它们之间没有联系。阅读并提供所有相关信息。您使用哪种标准库实现?等等@Ajay Brahmakshatriya您需要告诉编译器如何生成FP代码。M4 FPU具有单精度sqrt指令Cortex-M4F不支持VPF指令。它只有一个小型的单精度FPU。OP需要仅支持FPU的单精度浮点。而在小型裸机上连接libc通常不是一个好主意。但是,更多的信息很难说。@Olaf需要更多的努力来归档它。应为核心/FPU组合编译libc和libm。VPF?你是说VFP吗?它确实支持v4@PeterJ_01:因此,应建造/安装带有多拱支架的arm one eabi。是的,我的意思是VFP(嗯,也许我在这方面有点错)<代码>因此,应该构建/安装具有多拱支持的arm none eabiLinaro(我认为他使用它)无论如何都是多拱的。我已经尝试编译了您的代码,但我仍然有sqrtf的软件实现,尽管关闭了errno by-fno math errno标志。我有用于硬浮点的libgcc——sqrtf的实现使用硬件FP函数。你知道为什么使用你认为这个问题没有解决的所有标志吗?@Esato到底是什么意思?我建议安装openSTM32,因为它与mulitiarch工具链一起提供。如果您安装,我可以为您生成具有正确设置的项目。感谢您的建议,但我无法在现有项目中设置新项目和更改工具链。相反,我想知道为什么我的toolchaing中的适当标志仍然生成冗余代码来处理数学错误。我的微控制器是nRF52832。