Misra violation 12.6 - c

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

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.

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;

How about this:
A = (B == 0 ? 1 : 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"

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.

Related

-Wint-in-bool-context warning issue in some compilers

I am a getting warning:
warning: '<<' in boolean context, did you mean '<' ? [-Wint-in-bool-context]
for the code similar to the following:
int a=7,b=3;
int index=((a<<1)||b)&&5;
To explain the rationale behind such warnings:
C did get a boolean type _Bool/bool as per C99, but no changes were done to the behavior of the various logical operators of the language. That is:
Equality operators ==/!=
Relational operators <,<=,>,>=
Logical AND &&
Logical OR ||
Logical negation !.
Despite C having a boolean type, all of these operators return type int with value 1 or 0. Unlike C++ where all of these operators actually return type bool with value true/false. This is a known flaw of C.
It's common good practice however to treat such expressions as if they were boolean. Coding guidelines like MISRA C encourage the use of a fictional type "essentially boolean", meaning any expression that could be treated as _Bool. The reason for this is that it makes code more self-documenting and also makes it harder to create various typo-related bugs.
For example if(str) could mean check for NULL, or it could mean check for null termination but oops we forgot to dereference. Same thing with if(*str). Whereas if we only pass the result of a logical operator to if, the code becomes much clearer and it becomes harders to write bugs: if(str != NULL) could only mean check for NULL and if(*str != '\0') could only mean check for null termination.
In your case, the || operator only cares if the operands are zero or non-zero ("essentially boolean"). In case a is non-zero then a<<1 will not change that. In case a is zero, then a<<1 is zero as well. Since the result is passed on to a logical operator, "in a boolean context", the shift is pointless - hence the warning. But of course a<<1 might take all kinds of other values in another context such as for example if(a<<1 & mask).
It would be reasonable to strongly suspect that you actually meant to write a<1 instead. Because that would yield either 0 or 1, where < is also a logical operator like ||.
I got the solution. We should avoid integers using with logical operators (eg. ||,&&). Using integers with bitwise operators (eg. <<,&,|,etc.) is fine.
Sometimes we don't get this problem while running on compilers because of low priority warning filters. In complex and warning sensitive compilers it comes up.
Thanks

How can I make my code in compliance with MISRA 2012 RULE10.4

if(fn1()) //Line 1
{
a++;
}
Here the return type of function fn1 is uint8_t. The function returns only values 0 or 1.
PC Lint throws error for line 1 says "Mismatched essential type categories for binary operator" [RULE 10.4 required]
Rule 10.4 says "Both operands of an operator in which the usual arithmetic conversions are performed shall have the same essential type category"
MISRA-C doesn't allow implicit checks against zero - all inputs to conditional statements must be "essentially boolean", which is what you get if you explicitly use logical operators like ==.
In addition, MISRA-C has various rules blocking you from mixing "essenitally signed" and "essentially unsigned" in the same expression, and thereby relying on implicit type promotions. So you can't write if (fn1() == 1) for that reason, since 1 is a signed type and there's also a rule requiring all integer constants to have u suffix.
So one possible fix is if (fn1() == 1u). However, since the function only returns 0 or 1, you can also cast its result to boolean type and that would be fine too: if ((bool)fn()). The best solution is however to rewrite the function to return bool, after which you can use if(fn1()).

Unpermitted operand to operator '!' [MISRA 2012 Rule 10.1, required]

Observing below Misra warning for below part of code.
Unpermitted operand to operator '!' [MISRA 2012 Rule 10.1, required]
Not sure what could be the fix here to get rid of this warning.
#define C_BYTE unsigned char
C_BYTE SessionStatus;
#define DISCONNECTED 0x10
if((!(SessionStatus & (C_BYTE) DISCONNECTED)))
{
//Do something
}
I tried a few chances but didn't work as below.
1)
if((~(SessionStatus & (C_BYTE) DISCONNECTED)))
{
//Do something
}
2)
if((!(SessionStatus & (C_BYTE) DISCONNECTED)) != 0u)
{
//Do something
}
The reason for the warning is that MISRA-C rule 10.1 expects the operand to the ! && || operators to be "essentially boolean". In your case it is actually an int, because of implicit type promotion rules.
Your 2nd example almost solved it, but you must convert to essentially boolean before applying !. That is:
if(!( (SessionStatus & (C_BYTE)DISCONNECTED) != 0u ))
This is ok since the result of the != operator is to be regarded as essentially boolean. So that code is MISRA-C compliant, but a bit hard to read. I would instead recommend this:
#define DISCONNECTED 0x10u // u suffix makes this essentially unsigned
...
bool disconnected = (bool) (SessionStatus & DISCONNECTED);
if(!disconnected)
By adding the u suffix to the integer constant, it is essentially unsigned, same type category as unsigned char. Therefore the & operation is valid without using any casts. However, we are not allowed to implicitly convert from essentially unsigned to essentially boolean, therefore add the cast to bool.
EDIT
Since SessionStatus & DISCONNECTED is a "composite expression", MISRA doesn't allow the result to be assigned or cast to a different or wider essential type. The rationale is that they fear incompetent programmers who believe that the calculation in for example (uint32_t)(u16a + u16b) is carried out with uint32_t because of the cast, which is of course nonsense. (It would be better to educate the programmers about basic C than to come up with artificial rules, but anyway...)
I'd advise to ignore this rule entirely, but if you can't for whatever reason, here's an alternative fix:
#define DISCONNECTED 0x10u
...
unsigned char disconnected = SessionStatus & DISCONNECTED;
if(!(bool)disconnected)
But of course this is worse code than my first example.

Bitwise AND operation on boolean values in C [duplicate]

I had the need to code a statement of the form
a = a || expr;
where expr should be evaluated and the result be assigned to a iff a is not set. this relies on the logical OR's short-circuiting capabilities.
The shorter way to write the above would, of course, be
a ||= expr;
but (to my surprise) C does not have logical assignment operators.
So my question is twofold. First, is there a shorter way to write the first statement in standard C (the ternary operator is even worse - a = a ? a : expr requires me to spell out a thrice).
Secondly, why aren't there logical assignments in C? The possible reasons I could think of are:
it makes the grammar harder to parse?
there is some subtlety in handling short-circuiting for these cases?
it was considered superfluous (but isn't that an argument against ALL the operator assignments?)
EDIT
Please unlock this question because:
The question it has been linked to (as a alleged duplicate of) HAS NOT BEEN ANSWERED. The (accepted) answer to that question states that ||= is not present because duplicates the functionality of |=. That is the wrong answer. |= does not short-circuit.
C and C++ are NOT the same languages. I wish to know why C doesn't have it. In fact, the fact that derived languages like C++ and, particularly, Java (which did not suffer from the problems of legacy code as has been suggested in Edmund's answer) makes the question even more interesting.
EDIT 2
It now seems like my original intent was wrong. In the statement a = a || expr (where a is integral and expr returns an integral value, first both a and expr will be implicitly converted to "booleans", and then the "boolean" value will be assigned to a. This will be incorrect — the integral value will be lost. Thanks, Jens and Edmund.
So for the first part of the question, the correct ways, not alternatives :), to code my intention would be:
if (!a) a = expr;
or
a = a ? a : expr;
they should be optimized the same (I think) though personally I would prefer the first one (because it has one less a to type).
However, the second part of the question still remains. The arguments that Jens and Edmund about have given about the ambiguity in a ||= expr apply equally well to a = a || expr. the assignment case can simply be treated as the normal one:
convert a to boolean
if it is true, the value of the entire expression becomes equal to the boolean value of a
otherwise evaluate expr, convert result to boolean, assign to a, and return it
The steps above seem to be the same for both the assignment and normal case.
a ||= expr is problematic due to short circuit evaluation of its equivalent a = a || expr.
To have a ||= expr function like a = a || expr consider OP's assertion:
"In the statement a = a || expr ..., first both a and expr will be implicitly converted to "booleans","
This is not quite correct. expr will not be converted if a evaluates to true. This would make a difference should expr be something like scanf() or rand() or some function that affected the state of the program.
Code such as a ||= scanf("%d", &i) != 1; would only attempt to scan data with a false value in a. Although it would be possible to extend the language this way, additional short-circuit operators to the current set of || and && would likely cause more coding problems than clear simplifications.
On the other hand: A quick, if obfuscated, way to write code where functions return non-zero codes on error.
// Perform functions until an error occurs.
bool error = foo1();
error &&= foo2(); // Only valid if C was extended with &&=
error &&= foo3();
Because the return type of operators || and && is not the same as type of their left argument.
The return type of || and && is always int1, while the left argument may be any integral, floating point or pointer type. The operands also don't have to be of the same type. Therefore defining x ||= y as x = x || y and x &&= y as x = x && y as would be consistent with other augmented assignments would not be able to store the result in the argument for most types.
You could come up with other definitions, e.g. x ||= y as if(!x) x = y and x &&= y as if(!y) x = y, but that would not be exactly obvious and it is not that useful, so it was not included.
1In C++ it is bool.
I guess the simple answer is that || is a boolean operator: and in C, a "boolean" is 0 or 1. The operands are implicitly converted to booleans (I have not checked that that's what the spec actually says, but it's how C behaves), and the result is a boolean.
Altering the semantics to support this pattern may well be feasible -- until someone relies on || doing what it's always done.
I cannot find any particular reason, why the operators don't exist (in C99).
So the only reason I can find is, that there was no boolean type in C89, and those boolean operators were intended to be solely used in if's.
Example:
int i = 5;
/* This should not make any difference,
since or'ing with false, shouldn't change
the value... dib di dib diddy...*/
i ||= 0; /* Actually: i = i || 0, which gives 'true' */
i is now '1'', which for most people is pretty counter intuitive.
This operator obviously doesn't bring any clearence or coding improvement without the boolean type, that would make sence being or'd with another one.
In my opinion, the implementation of a ||= b; as if(!a) a = b; would be pretty straightforward and has aleardy been implemented by e.g. Lua.
So you're question seems to be a bit, why C has been designed the way it has been designed.
If this question was about C++, you could for example ask Bjarne Stroustrup and ask him, what had went into him. Since this is not the case, this seems to me to be kind of a dead end, because the standard has been written quite some time ago and you cannot really ask people anymore, why the h***.
On the other hand, this incomplete operator set should (in my opinion) aleardy have been made whole using a similar notation than yours, since in my opinion, there is no reason against it.
I hope I could help a little.
One simple explanation is this.
bool resultsComputeAll = false;
bool resultsUntilFirst = false;
for (int i = 0; i < 10; ++i) {
resultsComputeAll = compute(i) || resultsComputeAll;
resultsUntilFirst = resultsUntilFirst || compute(i);
}
Which one would be result ||= compute(i)? It's ambiguous so it's better to not define.

Signed/unsigned mismatch

I'm having hard time understanding nature of issue I encountered in my code.
Line
if ((struct.c == 0x02) && (struct2.c == 0x02) && (struct.s == !struct2.s))
{/**/}
where c is int and s is uint64_t produces
C4388:'==' signed/unsigned mismatch
warning. I understand what that warning is, I can't see what is triggering it here. What am I missing?
Directly quoting the C11 standard, chapter §6.5.3.3, (emphasis mine)
The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int....
So, the result of the logical ! operator is int, so !struct2.s produces int value, and the expression
....(struct.s == !struct2.s)
creates the issue.
NOTE 1:
I guess you use struct as a structure name just for illustration purpose, otherwise, struct being a reserved keyword in C you cannot use that as a variable name.
NOTE 2:
Maybe what you actually meant is (struct.s != struct2.s), but that's also just a (probable)guess.
FOOTNOTE :: Earlier question tagged C++ also, Moving it as footnote but keeping the info just for reference.
Regarding C++, the return type of ! is bool. Ref: C++11, chapter § 5.3.3 (again, emphasis mine)
The operand of the logical negation operator ! is contextually converted to bool(Clause 4); its value istrueif the converted operand isfalseand false otherwise. The type of the result is bool.
[too long for a comment]
To get the most out of compiler warnings, always try to put only one statement/expression on one line (at least temporarily when trying to determine the error's/warning's source).
So if you'd have set the code this way:
if (
(struct.c == 0x02)
&& (struct2.c == 0x02)
&& (struct.s == !struct2.s)
)
You'd been pointed by the compiler to exactly the (relativly) 4th line.

Resources