逻辑运算符的右手操作数 ||由于调用函数而具有持久的副作用(MISRA-C 2012Rule 13.5)

The right hand operand of a logical operator || has persistent side effects because of calling function (MISRA- C 2012Rule 13.5)

逻辑运算符的右手操作数||由于调用函数 detectError().

有持续的副作用
if ( ( detect() == VALID ) || 
         ( detectError() == INVALID ) )
    {
        up( a,b );  
      }
typedef enum
{

C;

}E_name;
typedef struct
{
 
 E_name be:4;
  
}S_name;
S_name name;

persistent_side_effect: 表达式 name.be = C 具有持久的副作用:修改非局部对象 okay.be = C.

sint16 detectError(void)
{
name.be = C;
}

我能解决逻辑运算符&&,有||的解决方案吗?运算符?

当然,最简单的解决方法是:

whateverType detectFlag1 = detect();
whateverType detectFlag2 = detectError();

if ( ( detectFlag1 == VALID ) || ( detectFlag2 == INVALID ) )
{
   up( a,b );  
}

简单、清晰的代码,没有潜在的副作用?

一般来说,具有 MISRA-C 质量问题的代码需要是确定性的,并且应该至少存在一个执行部分代码的用例(代码覆盖率)。在这种情况下,无法判断 detectError() 是否被调用,这可能会或可能不会有问题,具体取决于该函数是否包含任何副作用。

此外,常识与“如果检测有效或检测错误无效”并不相符。这甚至应该意味着什么,如果检测失败但您无法检测到错误,那么这不会使您的程序处于未定义状态吗?

当然我不知道这些函数在做什么,但至少可以考虑更好的标识符命名。也许“检测错误”应该被称为“获取最后一个错误”之类的。

假设代码是正确的,那么您可以像这样以更清晰但等效的方式重写它:

if(detect() == VALID)
{
  up(a, b);
}
else if(detectError() == INVALID)
{
  up(a, b);
}
else
{
  ; // possibly handle this scenario or leave it blank
}

请注意,根据 MISRA-C 防御性 programming/self-documenting 代码,else 是强制性的。


其他问题:

  • 在 MISRA-C 应用程序中使用位域是一个非常糟糕的主意。 MISRA-C 不禁止它们,但它们通常不可移植且标准化程度低,因此它们不属于确定性或可移植程序。
  • 不要为 sint16 这样的整数制定自制的车库标准。请改用 stdint.h 中的标准 C sint16_t。如果您坚持使用 C90,则根据 stdint.h 名称制作 typedef。