Reputation: 23
i need some help with a piece of code. I have an array, lets call it array[4]. Now I want to check that at least 3 elements of this array are taller than a threshold. (if statement)
E.g.
if(2 > ((array[0] > threshold) + (array[1] > threshold) + (array[2] > threshold) + (array[3] > threshold) ))
Here Misra is complaining. (Rule 10.1 Unpermitted operand operator "+") Is there another way to code this if statement without checking every possible permutation ?
Cheers
Upvotes: 0
Views: 390
Reputation: 214730
The MISRA warning is because you attempt to do arithmetic on types that are "essentially boolean" which is nonsensical.
But that's the least of your problems, this line of code is plain awfully written, to the point where one will suspect deliberate obfuscation. It does not "check that at least 3 elements of this array are taller than a threshold". It can't be salvaged.
One way to re-write this code is (MISRA-C:2012 compliant):
uint32_t above_count=0;
for(size_t i=0; i<N; i++) // where N is some named variable for the amount of items / array size etc
{
if(array[i] > threshold)
{
above_count++;
}
}
if(above_count >= 3) // "check that at least 3 elements of this array are taller than a threshold"
{
...
}
Upvotes: 0
Reputation: 2322
At the heart of this question is a misunderstanding... that a boolean true
is of the value 1
and false
is 0
- and that you can add three booleans together.
A boolean is either true
or it is false
.
Mathmatically, the +
operator makes no sense with a boolean: and that is the rationale for this particular MISRA Rule (see also the Appendix explaining Essential Types)... it doesn't help that the C implementation of boolean is so broken.
The other answers offer alternatives. But one plea, spare us the yoda conditionals, especially as you appear to have it the wrong way around for your explanation... if ( 2 > ... )
is not even your false condition, it needs to be if ( 2 < ... )
Upvotes: 0
Reputation:
How about unpacking the one-liner, possibly to a loop? It could be more readable too:
int check = 0;
for (int i = 0; i<4; i++) {
if (array[i] > threshold) {check++;}
}
if (check >= 3) ...
Your if statement actually appears to be testing something else "at least 3 are taller" vs if (2 > ...)
(at most one?).
Upvotes: 2
Reputation: 6826
How about explicitly converting those pesky non-addable booleans to integer 1/0?:
if(2 > ((array[0] > threshold?1:0) + (array[1] > threshold?1:0) + (array[2] > threshold?1:0) + (array[3] > threshold?1:0) ))
Upvotes: -1