我在智慧结束时。我无法让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)
答案 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。