1

我收到以下代码示例片段的 MISRA QAC 警告。那就是“控制表达式的值不是从显式逻辑运算中派生的”。

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

文件.c

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


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

2 回答 2

4

您的代码有以下 MISRA-C:2012 违规:

  • 规则 8.2 函数应为带有命名参数的原型格式。

  • 规则 8.4 当定义了具有外部链接的对象或函数时,兼容的声明应可见”。

  • 规则 17.3 函数不应被隐式声明

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

这些问题都与布尔值无关。值得注意的是,MISRA-C 没有规则“控制表达式的值不是来自显式逻辑运算”。相关的 MISRA-C 规则是

if规则 14.4语句 /--/的控制表达式应具有本质上的布尔类型。

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

MISRA-C:2012 的不同之处在于,他们明确提到该工具必须有一些方法来配置它应该将哪种类型视为“基本上布尔”(在 2004 年称为“有效布尔”),以防您不使用C99 布尔类型。

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

此外,没有可见的先前函数声明的 C90 函数隐式假定该函数返回int. 但是由于上面提到的 3 条规则,MISRA-C 检查器绝不应该让这样的代码通过。

修复特定错误的解决方案:

  • 询问您的工具供应商如何配置该工具,以便它知道哪种类型被视为“本质上是布尔值”。
  • 或者,将代码修补到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 规则以及必须维护您的代码的同事的麻烦。

于 2020-02-28T12:31:36.443 回答
2

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

于 2020-02-28T11:40:15.287 回答