我有些纠结于导致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,必填]
谢谢
答案 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