gpt4 book ai didi

c - 覆盖 GCC 的可变参数参数提升

转载 作者:太空狗 更新时间:2023-10-29 15:31:06 27 4
gpt4 key购买 nike

我正在为运行 Cortex-M4 架构的 ARM 处理器编写一段代码(具有单精度 float 但不是 double float )。我遇到的问题是在使用可变参数时,编译器试图将我的 float 提升为 double 。有什么办法可以关闭它吗?或者指定不同的促销策略?我查看了 GCC 手册,但找不到任何内容。一个简单的例子是尝试编写您自己的 printf...

void myprintf(const char *fmt, ...) {
// .. parse fmt and come across %f

double dv = va_arg(args, double); // Compiles but doesn't link

float fv = va_arg(args, float); // Doesn't compile (warns about promotion)
}

更新:根据要求,我希望使用的调用命令是 myprintf("%f", 1.0f);。问题是 Cortex-M4 不支持 double ,所以当 1.0f 提升为 double 时……它不能。所以使用 va_arg(args, double) 读回它会编译但不会链接,因为与 double 相关的各种 __aeabi_ 函数不存在。我想做的是禁用 GCC 将 float 提升为 double (如果可能)。

更新:我有一个当前的解决方法,它基本上只接受指向 float 而不是 float 的指针。我仍然想禁用促销,因为这不是一个很好的解决方案。

最佳答案

将可变参数 float 参数转换为 double 不是 gcc 怪癖或附加组件。它是 C 标准所要求的。 §6.5.2.3(函数调用):

  1. If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. …
  2. If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

Gcc 确实提供了一些与 C 标准不兼容的选项,但绝大多数选项仅在标准不兼容的情况下才添加行为。这种幅度的变化会影响标准调用约定,使编译后的代码与其他编译后的代码(例如库、标准或其他)不兼容。 Gcc 不提供这样的选项。其他编译器可能,但我不知道有哪个编译器可以。

请注意,如果 float 是一个32 位值。 §5.2.4.2.2 中的最低精度要求有效地要求除指数和符号外, double 至少具有 32 位尾数。这比 64 位 IEEE-749 double 提供的精度低很多,但显然比 32 位值提供的精度要高。

编译器当然有可能提供一个选项,其中 double 以不太精确但计算速度更快的格式表示,例如两个 float,其中尾数不重叠。 (也就是说,指数至少相差尾数的宽度。)至少一个遗留实现 IIRC 使用了该表示或类似的东西,正是因为它允许将单精度硬件用于 double 计算.它还使将 float 转换为 double 变得微不足道;只需要使低位值为 0.0。或者,编译器可以使用 32 位尾数结合 short 指数,这允许使用整数 ALU。

不过,我认为 GCC 也没有提供该替代方案。

关于c - 覆盖 GCC 的可变参数参数提升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58178731/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com