我该怎么做才能避免MISRA为下面的代码提供此错误?我尝试使用(unit16_t)进行投射.但后来它不允许显式转换.
在复杂表达式中从基础MISRA类型"unsigned char"到"unsigned int"的非法隐式转换(MISRA C 2004规则10.1)
uint8_t rate = 3U; uint8_t percentage = 130U; uint16_t basic_units = rate * percentage;
问题在于,整数提升会默认地将速率和百分比提升为"int"类型.因此,乘法是在有符号类型上执行的.
MISRA兼容代码要么将代码重写为
uint16_t basic_units = (uint16_t)rate * (uint16_t)percentage;
Run Code Online (Sandbox Code Playgroud)
或者按照MISRA的建议,立即将表达式的结果强制转换为其"基础类型":
uint16_t basic_units = (uint8_t)(rate * percentage);
Run Code Online (Sandbox Code Playgroud)
编辑:澄清如下.
ISO 9899:1999 6.3.1.1 2
如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int.这些被称为整数促销.
来自MISRA-C的信息性文本:
MISRA-C:2004 6.10.3危险类型转换:
/ - /
- 更改算术运算中的签名:积分提升通常会导致两个无符号操作数产生类型(signed)int的结果.例如,如果增加了两个16位无符号的操作数的将产生一个符号的32位结果INT是32位,但在无符号的16位的结果,如果INT为16位.
我实际上不确定我的上面的第二行是否会满足MISRA,我认为我可能已经将MISRA 10.1与10.5混淆了,后者强制立即转换为基础类型,但仅限于某些按位运算符.
我使用LDRA静态代码分析对这两行进行了测试,并没有抱怨(但是提供了一些不正确的,不相关的警告),但是LDRA在MISRA-C上的表现也很差.
不管怎样,在原来的问题,问题是速度和百分比都隐含整数促销转换为类型INT这是签署了,因为INT可以表示uint8_t的所有值.所以它变成了
uint16_t basic units = (int)rate * (int)percentage.
Run Code Online (Sandbox Code Playgroud)
为了防止这种情况,你必须明确地进行类型转换.在考虑之后,我会选择上面两条线的第一线.