user3563075
user3563075

Reputation: 1

MISRA Warning<The complex expression is implicitly converted to a different essential types.>

MISRA C++ rule: 5_0_3

Tried with one of the MISRA compliant static tool analyzer and couldn't resolve it.

#include<iostream>
#include<stdlib.h>

using namespace std;

int main()
{
    uint32_t num = 0U;
    bool Flag =false;

    num |= (Flag ? (0b10 << 10):(0b00 << 10));
}

Please help in getting resolve this. Error messages are: 1. The non-constant operands to this binary bitwise operator have different essential types. 2. This complex expression is implicitly converted to a different essential type.

Upvotes: 0

Views: 1140

Answers (1)

Lundin
Lundin

Reputation: 213892

First of all the 0b syntax is non-standard, so there's no telling what it will do. That syntax alone is a MISRA violation; I'd recommend to use hex constants instead. At any rate, your code shouldn't contain any "magic numbers".

If we assume that your compiler treats non-standard 0b integer constants as it treats regular decimal integer constants, then their type is (signed) int. The result of your operation is of signed int, "essentially signed" as MISRA would call it. But you store it in a uin32_t which is essentially unsigned, which is a MISRA violation and the reason for the error.

Please note that the shift operators always have the type of the integer promoted left operand. So writing something like 0b10 << 10u wouldn't help. As a rule of thumb, never use bitwise operators on signed operands.

Also note that the ?: is peculiar as it contains an implicit conversion of the 2nd and 3rd operands - they are balanced to the same type (according to "the usual arithmetic conversions"). This can create subtle bugs, so it is best to stay clear of ?: when using small integer types or signed types (or when using MISRA, for that matter).

I would also recommend to re-write the code to something with less "magic numbers":

#define MASK_SOMETHING  (0x2u << 10) // give this some meaningful name
#define MASK_EMPTY      (0x0u << 10) // give this some meaningful name

uint32_t num = 0U;
bool Flag = false;

...

if(Flag)
{
  num |= MASK_SOMETHING;
}

Obviously bitwise OR against zero isn't very meaningful, maybe you meant to clear the bits instead if the Flag isn't set? In which case you need else { num &= ~MASK_EMPTY; }.

(This can also be optimized further to get rid of the branch.)

Upvotes: 1

Related Questions