MISRA - 禁止转换复数整数表达式:Signed与Unsigned

时间:2018-01-30 20:03:05

标签: c implicit-conversion misra

我在智慧结束时。我无法让MISRA停止抱怨。

typedef unsigned char T_u8;
typedef signed char T_char;
T_u8 value = 0u;
T_char out[some_length];

开始

out[size_out--] = (( value | 0x30) );
scm.c  320  Note 960: Violates MISRA 2004 Required Rule 12.7, Bitwise operator applied to signed underlying type: |
scm.c  320  Info 734: Loss of precision (assignment) (8 bits to 7 bits)

不确定。说得通。我会改变它,所以我是或者是相同的类型。

out[size_out--] = (( value | 0x30u) );
scm.c  320  Info 713: Loss of precision (assignment) (unsigned int to char)

因此,使用OR表达式,表达式将被提升为unsigned int。所以,我应该将它转换为它所期望的类型。

out[size_out--] = (T_char)(( value | 0x30u) );
scm.c  320  Note 960: Violates MISRA 2004 Required Rule 10.3, Prohibited cast of complex integer expression: Signed versus Unsigned

现在怎样?我不明白。为什么我不能施展它?我该怎么办?

out[size_out--] = (T_char)((T_u8)( (T_u8)value | (T_u8)0x30u) );
scm.c  320  Note 960: Violates MISRA 2004 Required Rule 10.3, Prohibited cast of complex integer expression: Signed versus Unsigned

这没有帮助:

out[size_out--] = (( (T_u32)value | (T_u32)0x30) );
scm.c  320  Info 713: Loss of precision (assignment) (unsigned long to char)

1 个答案:

答案 0 :(得分:2)

第一个问题是你使文字无符号,这确实是必需的。然而,这使得表达式value | 0x30u隐式转换为不同签名的不同“基础类型”(MISRA-C:仅2004年术语)。规则10.1。

您可以通过在应用|运算符之前强制显式转换来解决此问题:

out[size_out] = (unsigned int)value | 0x30u;
size_out--;

请注意,将++或 - 与同一表达式中的其他运算符混合会违反另一条MISRA规则,原因很充分,因为这样做是危险的做法。

以上应该足以满足MISRA-C:2004,尽管仍有隐式转换(左值转换)回到char类型。这并不违反MISRA,但你的工具显然还会抱怨它。这不是MISRA警告:

  

“信息713:精度损失(分配)(无符号长到字符)”

这是一个相当迂腐的警告,尽管你可以添加额外的演员阵容以使其消失:

out[size_out] = (T_char)((unsigned int)value | 0x30u);

MISRA的主要目的之一是启发程序员关于隐式类型促销如何在C语言中起作用。它们是语言的最大缺陷之一,直到你研究它们是如何工作的(它们并非完全无关紧要),可能会忘记编写符合MISRA标准的代码。或者无错误的代码。我试图解释最常见的工作方式:Implicit type promotion rules

我还建议您升级到MISRA-C:2012。这是一个更合理的文件,解决了MISRA-C:2004的许多问题。例如,“基础类型”的概念被替换了。

最后,你真的应该开始使用stdint.h而不是使用你自己的非标准typedef。