MISRA 违规“441 - 浮点数转换为非浮点数”

MISRA violation "441 - Float cast to non-float "

我正在尝试更正使用以下代码发生的 MISRA 违规“441 - 浮点数转换为非浮点数”:

tULong frames = (tULong)(runTimeSeconds * 40.0f);

runTimeSecondsfloat 并且显然 40.0f 被分配为 float。有什么想法吗?

如果要截断结果,请使用 truncf 函数:

ULong frames = truncf(runTimeSeconds * 40.0f);

这样,你的意图就明确了。

<math.h> 有一组很好的函数,可以在一次调用中进行舍入和转换。无需转换即可从 float 转换为 tULong。下面有一个 (tULong) 转换来处理整数到整数的转换,这可能会根据未发布的范围问题和 tULong 详细信息而被消除。

#include <math.h>
// long int lrintf(float x);
// long long int llrint(double x);
// 4 others

tULong frames = (tULong) llrintf(runTimeSeconds * 40.0f);

这四舍五入而不是像 OP 的原始代码那样截断。

有一条规则 (MISRA-C:2004 10.4) 说明浮点类型的复杂表达式的值只能转换为更窄的浮点类型。

(runTimeSeconds * 40.0f) 就是这样一个 so-called 复杂表达式 (MISRA-C:2004 术语)。为了避免 MISRA 违规,可以引入一个临时变量:

float tmp = runTimeSeconds * 40.0f;
tULong frames = (tULong)tmp; // no complex expression, this is fine

此规则的基本原理是复杂的表达式可能包含隐式类型提升和类似的危险事物。

MISRA-C:2004 也是 worried/paranoid 无能的程序员,他们认为将 uint8_t u8a, u8b; ... u8a + u8b 之类的代码更改为 (uint32_t)(u8a + u8b) 会以某种方式导致添加作为无符号 32 位类型。


这些规则在 MISRA-C:2012 中得到了改进,并且在那里更加合理。根据 MISRA-C:2012 10.5.

,从浮点表达式到无符号表达式的转换是可以的