简体   繁体   中英

Misra Violation 10.1 regarding statement operations (MISRA C 2012)

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)

Eg

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

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?).

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 <... )

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"
{
  ...
}

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) ))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM