MISRA C:2004 10.5查询

时间:2018-08-07 11:58:50

标签: c misra

我有些纠结于导致MISRA C 2004 10.5违规的代码的一部分,但无法确定到底是什么原因。

我已定义此MACRO以获得2的幂。

显示违规的代码是

#define tmM_pow2_16bit(x)   ((tm_uint16)((tm_uint16)1U<<((tm_uint16)x)))

来自静态分析工具的消息是

  

已签名数量的左移(int)[MISRA 2004规则10.5,必填]

谢谢

3 个答案:

答案 0 :(得分:2)

最可能的原因是移位运算符强制将(tm_uint16)1U隐式提升为int类型。

删除第二个强制类型转换,以确保您转换无符号类型:

((tm_uint16)(1U<<((tm_uint16)x)))

答案 1 :(得分:1)

问题可能是该工具无法完全弄清底层类型是什么。我怀疑它认为基础类型是unsigned int,因为那是1U的类型。

强制转换(tm_uint16)1U是多余的-在int为32位或更大的系统上,这只会强制转换为小整数类型,然后立即将其隐式转换为{{1 }}。那将是对MISRA-C:2004的违反,因为可能不会发生改变签名的隐式转换。我建议学习Implicit type promotion rules

int也是多余的,因为移位运算符的右操作数不参与确定操作数的结果。

MISRA-C:2004兼容代码应该是这样:

(tm_uint16)x

假设#define tmM_pow2_16bit(x) ( (tm_uint16)(1U << (x)) ) x类型有效。

(请注意,MISRA-C也不鼓励使用类似函数的宏。)

答案 2 :(得分:0)

用于检查MISRA-C遵从性的工具似乎坏了,但是从某种意义上说,您的确确实向左移了带符号整数类型int:在int大于16位的体系结构上,{ {1}}在转换发生之前被提升为(tm_uint16)1U,但这没有问题,因为它的值始终为正。

但是请注意,此宏中存在一个更糟的问题:int在扩展中未加括号,从而对诸如x之类的非平凡表达式造成了意外的行为。

您可以通过删除不必要的强制类型来修正警告:

tmM_pow2_16bit(1|2)

如果工具仍然抱怨潜在的左移量大于#define tmM_pow2_16bit(x) ((tm_uint16)(1U << (tm_uint16)(x))) 的位宽,请添加掩码:

int