且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么我的工具在这里抛出MISRA错误?

更新时间:2022-06-23 23:11:25

问题在于,整数促销将静默提升利率和百分比以键入"int".因此,乘法是在有符号类型上执行的.

The problem is that both rate and percentage are silently promoted by the integer promotions to type "int". The multiplication is therefore performed on a signed type.

MISRA兼容代码是将代码重写为

MISRA compatible code is to either rewrite the code as

 uint16_t basic_units = (uint16_t)rate * (uint16_t)percentage;

或按照MISRA的建议,立即将表达式的结果转换为其基础类型":

or do as MISRA suggests, immediately typecast the result of an expression to its "underlying type":

 uint16_t basic_units = (uint8_t)(rate * percentage);

进行澄清.

ISO 9899:1999 6.3.1.1 2

ISO 9899:1999 6.3.1.1 2

如果一个int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int.这些称为整数 促销.

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.

MISRA-C的内容丰富的文本:

Informative text from MISRA-C:

MISRA-C:2004 6.10.3危险的类型转换:

MISRA-C:2004 6.10.3 Dangerous type conversions:

/-/

-算术运算中有符号性的改变:整数提升通常会导致两个无符号操作数产生(signed)int 类型的结果.例如,如果 int 为32位,则将两个16位无符号操作数相加将产生一个有符号的32位结果,而如果 int 为16,则将产生一个无符号的16位结果.位.

- Change of signedness in arithmetic operations: Integral promotion will often result in two unsigned operands yielding a result of type (signed) int. For example, the addition of two 16-bit unsigned operands will yield a signed 32-bit result if int is 32 bits but an unsigned 16-bit result if int is 16 bits.

我实际上不确定上面的第二行是否满足MISRA,第二个想法是我可能将MISRA 10.1与10.5混淆了,后者将立即强制转换为基础类型,但仅在以下情况下:某些按位运算符.

I'm actually not sure whether the 2nd line of mine above would satisfy MISRA or not, at second thought I may have confused MISRA 10.1 with 10.5, where the latter enforces an immediate cast to underlying type, but only in case of certain bitwise operators.

我用LDRA静态代码分析测试了这两行,并且没有抱怨(但是给出了一些不正确的,不相关的警告),但是LDRA在MISRA-C上的表现也很差.

I tested both lines with LDRA static code analysis and it didn't complain (but gives some incorrect, non-related warnings), but then LDRA also performs very poorly at MISRA-C.

无论如何,原始问题中的问题是整数促销将隐含地将费率和百分比都转换为带符号的 int 类型,因为 int 可以代表所有uint8_t的值.变成了

Anyway, the problem in the original question is that rate and percentage are both implicitly converted by the integer promotions to type int which is signed, since int can represent all values of a uint8_t. So it becomes

uint16_t basic units = (int)rate * (int)percentage.

为防止这种情况,您必须显式键入.经过深思熟虑之后,我将选择上面两个中的第一行.

To prevent this you have to typecast explicitly. After giving it more thought, I'd go with the 1st line of my two above.