如何使 C 代码符合 MISRA C:2012 标准?

How to make C code to MISRA C:2012 compliance?

我正在使用 PC-Lint 验证我的 MCU 代码的 MISRA C:2012 标准。 我得到了关注 errors.Here 我发布了一个示例代码,其中我在条件语句中遇到错误。

1] 不带 'U' 后缀的无符号整数文字 [MISRA 2012 规则 7.2,必需] S_LCB_100,

2] 对逻辑运算符 '&&' 右手的副作用 [MISRA 2012 规则 13.5,必需] while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ))

3] :有符号值和无符号值不能一起用作 != [MISRA 2012 规则 10.4,必需] 的操作数 while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ))

4] :有符号值和无符号值不能一起用作 != [MISRA 2012 规则 10.4,必需] 的操作数 while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ) )

5] 无符号值和有符号值不能一起用作 == [MISRA 2012 规则 10.4,必需] if ( List[Loop] == 0x00000000 )

的操作数

如何使其符合 MISRA C:2012 标准?

typedef unsigned char UINT8;
typedef unsigned char BYTE;  
typedef unsigned long int UINT32; 
#define S_LCB_100 0xF0BB12DE;
#define MULTI 0x1A;
volatile static BYTE Counter = 0;
static UINT8 Loop = 0;    
static UINT32 List[]=  
{
    S_LCB_100,
    0x00000000,
};
while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ))
{
 .......some code
}
if ( List[Loop] == 0x00000000 )
{
.....some code
} 

一般备注:

  • 在担心 MISRA-C 合规性之前,先获取要在 C 编译器上编译的代码。
  • 然后确保您有可用的 MISRA-C:2012 文档,否则您根本无法使用 MISRA。
  • 摆脱像"Yoda conditions"这样的废话。
  • 摆脱自定义 typedef 并使用 stdint.h。如果您使用的是 C90,则 typedef 使用 stdint.h.
  • 使用的名称

1] unsigned integer literal without a 'U' suffix [MISRA 2012 Rule 7.2, required] S_LCB_100,

不言自明。将 Uu 添加到应无符号的整数常量。阅读规则 7.2 了解详情。

2] side effects on right hand of logical operator, '&&' [MISRA 2012 Rule 13.5, required] while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ))

Counter 是 voltatile 限定的,访问它是一个副作用。所以它一般不应该存在于复杂表达式中,特别是不应该出现在布尔 && 表达式的右侧——这是非常有问题的代码。在这种情况下,您可以简单地将代码重写为:

uint32_t count = (uint32_t)Counter;

while((count != 0u) && (List[Loop] != 0u))
{
  ...
  count = (uint32_t)Counter; // read volatile variable in an expression of its own
}

3] a signed value and an unsigned value cannot be used together as operands to != [MISRA 2012 Rule 10.4, required] while(( 0x00000000 != List[Loop] ) && ( 0 != Counter ))

这是因为 Counter 声明为 BYTE。删除所有此类自制垃圾类型并将其声明为 uint8_t。然后使用如上所示的 while 形式。使用 u 后缀。这应该修复 2) 到 5).