7

当我将 "%f" 说明符用于snprintftype 的参数时,我收到 MISRA 类型错误float

根据我的研究,MISRA 是正确的,因为 "%f" 需要一种double.

float是否存在将使用类型参数而不是 的浮点说明符或修饰符double

我正在开发嵌入式系统,不想double为了取悦snprintf功能而从 32 位浮点转换为 64 位。代码打印到调试/控制台端口,这是唯一发生转换的地方。

对于那些需要代码示例的人:

// This section is for those C++ purists and it fulfills the C++ tag.
#if __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif

#define BUFFER_SIZE (128U)

int main(void)
{
    char buffer[BUFFER_SIZE];
    float my_float = 1.234F;

    // The compiler will promote the single precision "my_float"
    //   to double precision before passing to snprintf.
    (void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float);
    puts(buffer);
    return 0;
}

我对 SO 和 Web 的所有研究都是关于打印一个浮点值,而不是关于哪些说明符需要一个float参数以便不会double发生任何提升。

我正在为 ARM7TDMI 处理器使用 IAR Embedded Workbench 编译器。

4

4 回答 4

21

不,因为printf和它的朋友都是可变参数函数,所以float参数会自动转换double默认参数提升的一部分(参见 C99 标准的第 6.5.2.2 节)。

我不确定为什么这会触发 MISRA 警告,但我想不出任何可能会造成危险的方式。

于 2013-01-09T01:40:04.140 回答
9

不,没有,因为标准提升将每个float参数转换为double当通过可变参数列表传递时。

于 2013-01-09T01:40:04.267 回答
5

正确的 MISRA-C:2004 合规性分析应给出:

  • 违反 1.1,代码不符合 ISO 9899:1990(C++ 代码,C99 代码)。
  • 违反 2.2,使用 // 注释。
  • 违反 16.1,使用可变参数函数。
  • 违反 20.9,使用 stdio.h。

如果您遇到上述错误以外的其他错误,则您的静态分析器可能已损坏。

我已经手动分析过,以及使用 LDRA Testbed 7.6.0。

于 2013-01-09T13:59:47.107 回答
0

由于自动升级,无法在 printf 函数中指定 float 而不是 double ,但我认为您可以更改代码:

(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float);

至:

(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", (double)my_float);

并取得正确的结果

于 2015-08-25T10:02:19.743 回答