下面的 C 代码有什么问题? MISRA 质量警告信息

What is the wrong in the following c code ? MISRA quality warning message

我收到以下代码示例片段的 MISRA QAC 警告。即'Value of control expression is not derived from an explicit logical operation.'

很明显,没有将 return 值分配给变量评估已经完成。此质量警告的确切原因是什么?

file.c

if(fun1())
{    
//statement1    
}    
else    
{    
//statement2
}


bool fun1()
{    
  return (bool) (Global_variable1 && Global_Variable2)    
}

调用 fun1() 不是 显式 逻辑表达式。显式形式为 fun1() == truefun1() != 0。是的,这似乎没有必要,但这正是警告所抱怨的。

您的代码存在以下 MISRA-C:2012 违规行为:

  • Rule 8.2 Functions shall be in prototype format with named parameters.

  • Rule 8.4 A compatible declaration shall be visible when an object or function with external linkage is defined".

  • Rule 17.3 A function shall not be declared implicitly

我希望兼容的工具至少给出上述错误之一。此外,兼容的 C99 或更高版本的编译器不会编译带有隐式 functions/implicit int 的代码。

None 这些问题与布尔值关系不大。值得注意的是,MISRA-C 没有规则 "value of control expression is not derived from an explicit logical operation"。相关的 MISRA-C 规则是

Rule 14.4 The controlling expression of an if statement /--/ shall have essentially Boolean type.

在 MISRA-C:2004 中,此规则称为 13.2,当时只是建议性的。这几乎是一条相同的规则。

MISRA-C:2012 的不同之处在于,他们明确提到该工具必须有一些方法来配置它应将哪种类型视为 "essentially Boolean"(在 2004 年称为 "effectively Boolean"),在如果您没有使用 C99 bool 类型。

如果您的工具不知道将哪种类型视为本质上的布尔值,它会将您的 C90 自制 bool 视为 int。然后它会认为 if 语句使用了 int,这违反了规则。

此外,没有可见函数声明的 C90 函数隐式假定函数 returns int。但是由于上面提到的 3 条规则,MISRA-C 检查器永远不会让这样的代码通过。

具体错误的解决方案:

  • 询问您的工具供应商如何配置工具,以便它知道哪种类型被视为 "essentially Boolean"。
  • 或者,将代码修补到 if(fun()==true),但您真的不需要为了 MISRA 合规性而这样做。

获取MISRA-C:2004/MISRA-C:2012兼容代码的解决方案:

bool fun1 (void); /* you must declare the function before using it and it must use void */

...

if(fun1())
{    
  /*statement1*/   /* Note that you can't use // comments in C90 or MISRA-C:2004 */
}    
else    
{    
  /*statement2*/
}

...

bool fun1 (void) /* must use void */
{    
  /* return is not a controlling expression, no need for compound statements.
     No need to cast, the result of && is essentially boolean.
     MISRA-C:2004 has no requirement to cast to underlying type if using booleans.
  */
  return Global_variable1 && Global_Variable2;
}

请注意,使用全局变量可能会让您在使用其他 MISRA-C 规则时遇到麻烦,也会给必须维护您的代码的同事带来麻烦。