I am getting MISRA QAC warning for the following code sample snippet. That is 'Value of control expression is not derived from an explicit logical operation.'
It is clear that without assigning the return value to a variable evaluation has been done. What is the exact reason for this quality warning?
file.c
if(fun1())
{
//statement1
}
else
{
//statement2
}
bool fun1()
{
return (bool) (Global_variable1 && Global_Variable2)
}
Your code has the following MISRA-C:2012 violations:
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
I'd expect a compliant tool to give at least one of the above errors. In addition, a compliant C99 or later compiler will not compile code with implicit functions/implicit int.
None of these problems are the slightest related to booleans. Notably, MISRA-C has no rule "value of control expression is not derived from an explicit logical operation". The relevant MISRA-C rule is
Rule 14.4 The controlling expression of an
if
statement /--/ shall have essentially Boolean type.
In MISRA-C:2004 this rule is called 13.2 and was just advisory back then. It was pretty much an identical rule.
What's different in MISRA-C:2012 is that they explicitly mention that the tool must have some means of configuring which type it should treat as "essentially Boolean" (called "effectively Boolean" in 2004), in case you aren't using the C99 bool type.
If your tool does not know which type to regard as essentially Boolean, it will treat your C90 home-made bool
as an int
. And then it will think that the if
statement is using an int
, which would have been a violation of the rule.
In addition, C90 functions that have no prior function declaration visible implicitly assume that the function returns int
. But because of the 3 mentioned rules above, the MISRA-C checker should never let such code through.
Solution to fix the specific error:
if(fun()==true)
, but you really shouldn't need to do that just for MISRA compliance.Solution to get MISRA-C:2004/MISRA-C:2012 compliant code:
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;
}
Please note that using global variables is likely to get you into trouble with other MISRA-C rules, and with co-workers who have to maintain your code.