我收到以下代码示例片段的 MISRA QAC 警告。那就是“控制表达式的值不是从显式逻辑运算中派生的”。
很明显,没有将返回值分配给变量的评估已经完成。此质量警告的确切原因是什么?
文件.c
if(fun1())
{
//statement1
}
else
{
//statement2
}
bool fun1()
{
return (bool) (Global_variable1 && Global_Variable2)
}
您的代码有以下 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 规则以及必须维护您的代码的同事的麻烦。
该调用fun1()
不是显式的逻辑表达式。显式形式是fun1() == true
or fun1() != 0
。是的,这似乎没有必要,但这正是警告所抱怨的。