Rule 0-1-6 seems to be counter productive with Boolean variables. DU dataflow anomalies are normal and desirable with Boolean variables. For example:
Code:
extern bool random_bool ();
bool non_compliant_and (void)
{
bool const b1 = random_bool();
bool const b2 = random_bool();
return b1 && b2; // b2 is DU dataflow anomaly when b1 is false
}
bool non_compliant_or (void)
{
bool const b1 = random_bool();
bool const b2 = random_bool();
return b1 || b2; // b2 is DU dataflow anomaly when b1 is true
}
bool compliant_and (void)
{
bool const b1 = random_bool();
bool const b2 = random_bool();
bool tmp = b1;
tmp = b2 && b1;
return tmp;
}
bool compliant_or (void)
{
bool const b1 = random_bool();
bool const b2 = random_bool();
bool tmp = b1;
tmp = b2 || b1;
return tmp;
}
The compliant and non-compliant code result in different binaries. Both seem equally safe, but the compliant solution is less efficient. Which seems at odds with the statement in MISRA spec claims
Quote:At best this (DU dataflow anomaly) is inefficient, but may indicate a genuine problem.
Is there any insight anyone can provide on such a perplexing problem?
Ehm, did you accidentally switch the compliant function body with the non-compliant one?
compliant_and + compliant or violate 0-1-6 as well as 0-1-9.
Unfortunately the function bodies are not switched.
Code:
bool non_compliant_and (void)
{
bool const b1 = random_bool(); // Assume this value is false.
bool const b2 = random_bool(); // This can be any value.
/* Due to short-circuit evaluation, the value of b2 is never evaluated (read).
* This causes a DU dataflow anomaly for b2, and hence the MISRA C++ Rule 0-1-6 violation.
*/
return b1 && b2;
}
The short-circuit evaluation is a required part of the language:
C++ reference on logical operators
I ran your example through
https://gimpel.com/demo.html with settings "C++11, No standard library, MISRA C++ 2008" and non_compliant_and + non_compliant_or are in fact shown as compliant.
I also fail to see a violation of 0-1-6 there, unless function random_bool returns a fixed value.
On the other hand, compliant_and + compliant_or violate both 0-1-6 and 0-1-9 and I agree.
The only real problem with short circuit evaluation are constructs like this (violating rule 5-14-1):
Code:
return b1 && random_bool();
It does show up with the Coverity scanner from Synopsys, and I don't believe that it is a false positive either. I also believe Synopsys is interpreting the rule correctly here. Is this case a slight over sight of the MISRA committee? Am I wrong in my analysis? I don't have a problem with being wrong. I just want some feedback from the experts.
If Coverity were right, you wouldn't be able to use operator && || etc. at all.
I am pretty sure this is not what MISRA had in mind.
But I am afraid we have to wait for an official reply.
We don't see why any static analyser would report 'non_compliant_and' as non-compliant. If random_bool indeed generates a random boolean value, then you can't assume that its false, so both terms may be used in b1 && b2.
The DU anomaly should only be reported when code can never be used, like false && b2;
Similarly with 'non_compliant_or'
Thank you. That is very helpful information. I will pass this information on to the Coverity folks.
This clarification of the rule seems to be contrary to the first example provided in spec.
Code:
int16_t critical (int16_t i, int16_t j)
{
int16_t result = 0;
int16_t k = ( 3 * i ) + ( j * j );
// should k be checked here?
if ( f2() )
{
// k will only be tested here if f2 returns true
// Initialization of k could be moved here
if ( k > 0 )
{
throw(42);
}
}
// Non-compliant- value of k not used if f2 () returns false
return result;
}
Is this also compliant because there is a path through the code where k is read?
I'm interested in a ruling too, as maintainer of the Coverity static analyzer. We based our analysis on the examples, which as mentioned seem to imply the code mentioned in this discussion is non-compliant.
I've always found rule 0-1-6 to be both confusing (with the title mentioning "never" but the example implying "not always", and a "DU anomaly" being mentioned but never defined. Searches for DU anomaly tend to reference cases of a use of an undefined value rather than non-use of a defined value) and counterproductive (as fixing any error tends to make the code signficantly more complex), but tried to do my best to enforce it as written.
I am not sure how to resolve the the conflicting information.
misra cpp post_id=3916 time=1606922742 user_id=962 Wrote:The DU anomaly should only be reported when code can never be used, like false && b2;
This information seems to conflict with the first example in the spec. I am not "trolling" the forum, I simply wish to understand the rule. For safety reasons I need to resolve the ambiguity.
The use of unqualified "never" in the headline is unfortunate.
The intent was that values given to a local variable should be used on all paths through a function on which the variable is accessible - as illustrated by the example.
This rule is under review for the next release
So, to make extra sure, does this mean that the non-compliant examples (non_compliant_and, etc.) at the origin of this discussion really are not compliant (contradicting the previous ruling, which itself seemed to contradict the examples)?
Short answer 'No'
We stand by both replies, return b1 && b2; etc. are compliant, the example with f2 and k isn't.
We think the bit of explanation that's missing is that the rule was not intended to apply to short-cut expressions
This rule is under review for the next version