5

How to get rid of MISRA violation on following statement

typedef unsigned char boolean;

boolean A, B;

A = !B;

Operand of logical ! operator is not an 'effectively Boolean' expression. MISRA-C:2004 Rule 12.6; REFERENCE - ISO:C90-6.3.3.3 Unary Arithmetic Operators

jinawee
  • 492
  • 5
  • 16
user3285192
  • 93
  • 2
  • 12
  • There is nothing wrong with your code - you simply need to log a deviation. See also Lundin's answer below. – Andrew Nov 06 '14 at 12:20
  • Is the distinction between `B` and `b` intentional? (C language is case sensitive). Does your static analysis tool know that your MISRA boolean type is `boolean`? (It might not be able to figure it out by itself, you might have to tell it). This just should be OK by MISRA (assuming it was supposed to be `A = !B`). Ternary operators in the answers also should not be necessary as for example a `var == 0` expression gives a boolean result, which can be assigned to a boolean variable right away without any voodoo magic. – Jubatian Dec 12 '14 at 13:19
  • its !B not !b. The question employs and undeclared variable. Please edit the question to !B. – AlphaGoku Nov 18 '16 at 08:44

5 Answers5

5

If you read rule 12.6 it says "check Boolean Expressions" in the appendix. There we can read

"Boolean-by-enforcement values can be introduced by implementing a specific type enforcement mechanism using a tool. A Boolean type could be associated with a specific typedef, and would then be used for any objects that are Boolean. This could bring many benefts, especially if the checking tool can support it, and in particular it could help avoid confusion between logical operations and integer operations."

MISRA-C:2004 assumes C90, and in C90 there is no bool type, you have to typedef it yourself, like you have done. Since your intention is to have a type which is effectively boolean, the code is just fine. In fact, your code follows MISRA recommendations beyond the mandatory ones.

The problem lies with your tool: it either does not support to allow a specific boolean type as per MISRA recommendations, or it is misconfigured.

Lundin
  • 195,001
  • 40
  • 254
  • 396
2

Simple... don't use ! on things that aren't booleans. Just because your typedef is named boolean doesn't mean it is; it's still an unsigned char.

You could write:

if (b == 0) A = 1;
else A = 0;

I don't think MISRA allows ternary operators (could be wrong; not an expert) but if it does, you could write:

A = (b == 0) ? 1 : 0;
TypeIA
  • 16,916
  • 1
  • 38
  • 52
  • 2
    Misra do allow ternary operator – user3285192 Feb 13 '14 at 17:23
  • Great guys its seems like a good solution need to find out . autocode genrator gernate code this . thanks – user3285192 Feb 13 '14 at 17:30
  • "Just because your typedef is named boolean doesn't mean it is; it's still an unsigned char" This is not correct as far as MISRA is concerned. What matters is what you intend to use the variable for. The variables in the OP's post are effectively Boolean so his code is just fine. – Lundin Feb 14 '14 at 08:49
  • 2
    The intention of MISRA is always to make you actually think about what types you are using in an expression. The intention of MISRA is never to have you writing obfuscated code to sate a broken static analysis tool. – Lundin Feb 14 '14 at 08:50
1

How about this:

A = (B == 0 ? 1 : 0);
  • 3
    The intention of MISRA is always to make you actually think about what types you are using in an expression. The intention of MISRA is never to have you writing obfuscated code to sate a broken static analysis tool. – Lundin Feb 14 '14 at 08:50
0

Though the ISO:C90 standard says the operand can be of any scalar type the ! operator always yield a value of either 0 or 1; the underlying type (in MISRA-C:2004 terms) is considered effectively boolean, but the operand is not. Since the operator interprets its operand in a Boolean sense by comparing it 0 with try:

A = (B==0);

which make the logical comparison explicit. Also, depending on the tool, there may a boolean type enforcement mechanism you can configure for this typedef.

  • The intention of MISRA is always to make you actually think about what types you are using in an expression. The intention of MISRA is never to have you writing obfuscated code to sate a broken static analysis tool. The operator `B` of `!B` is already boolean, so no obscure code is needed. See my answer for the relevant part of MISRA that says so. – Lundin Feb 14 '14 at 08:53
  • @Lundin, sorry I can’t comment other answers because of newbie contributor status. In general I agree you should not let MISRA force you to obfuscate code (it’s interesting you marked me down last week for making the same point when I suggested using a deviation, which BTW, a tool and proper process should make much less painful than changing the code). In this case, 12.6 is advisory, no deviation required. – Eddie Jones Feb 14 '14 at 20:44
  • 1
    @Lundin: However, your answer from App E is missing the first sentence: “Boolean-by-enforcement values can be introduced by implementing a specific type enforcement mechanism using a tool.” The tool is not broken. If you use a typedef, then the tool should have a type enforcement mechanism that can be configured with it (which a good MISRA tool can do), otherwise my suggestion is not only compliant to 12.6, its explicit. – Eddie Jones Feb 14 '14 at 21:03
  • Thanks, seems I goofed up copy/paste, fixed. And indeed it kind of sucks that you can't comment on other posts on SO from day 1... – Lundin Feb 17 '14 at 09:48
  • (I don't believe it was me who made the remark [here](http://stackoverflow.com/questions/21537030/how-to-make-1-9-pass-misra/21541915#215419159)? I merely pointed out that you didn't answer the question since you quoted a different MISRA version than the one asked for.) – Lundin Feb 17 '14 at 09:50
  • @Lundin, I answered the question, I did also added commentary outside of the question (because of the limitation) which I edited out. AFA MISRA-C:2012, it is very useful to referenced it for 2004 questions as it provides more insight and intent into the rationale of the earlier rules. – Eddie Jones Feb 25 '14 at 20:41
0

Have you tried the idiom !! to convert values in boolean:

bool bool_val = !!int_val;

Then the far-fetched following code might work:

A = !(!!B) // B is "cast" within the parenthesis then we apply the "NOT"
n0p
  • 3,399
  • 2
  • 29
  • 50
  • 1
    The static analyser is already complaining about `!B`, so adding further code outside that sub expression will solve nothing. – Lundin Feb 14 '14 at 09:45