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.