MISRA.CAST.UNSIGNED_BITSThe result of bitwise operation on unsigned char or short is not cast back to original type. MISRA-C Rule 10.5 (required): If the bitwise operators ~ and << are applied to an operand of underlying type ''unsigned char'' or ''unsigned short'', the result shall be immediately cast to the underlying type of the operand.When these operators (~ and <<) are applied to small integer types (unsigned char or unsigned short), the operations are preceded by integral promotion, and the result may contain high order bits which have not been anticipated. Exampleuint8_t port = 0x5aU; uint8_t result_8; uint16_t result_16; uint16_t mode; result_8 = (~port) >> 4; /* not compliant */ '~port' is 0xffa5 on a 16-bit machine but 0xffffffa5 on a 32-bit machine. In either case, the value of 'result' is 0xfa, but 0x0a may have been expected. This danger is avoided by inclusion of the cast as shown below: result_8 = ((uint8_t)(~port)) >> 4 ; /* compliant */ result_16 = ((uint16_t)(~(uint16_t)port)) >> 4 ; /* compliant */ A similar problem exists when the '<<' operator is used on small integer types and high order bits are retained. For example: result_16 = ((port << 4) & mode) >> 6; /* not compliant */ The value in 'result_16' will depend on the implemented size of an int. Addition of a cast avoids any ambiguity. result_16 = ((uint16_t)((uint16_t)port << 4) & mode) >> 6; /* compliant */ No cast is required if the result of the bitwise operation is:
MISRA-C++ Rule 5-0-10 (required): If the bitwise operators ~ and << are applied to an operand with an ''underlying type'' of ''unsigned char'' or ''unsigned short'', the result shall be immediately cast to the ''underlying type'' of the operand.RationaleWhen the operators ~ and << are applied to small integer types (unsigned char or unsigned short), the operations are preceded by integral promotion, and the result may unexpectedly contain high order bits. ExceptionThe immediate assignment of the result obtained by the use of ~ or << on an operand of type unsigned char or unsigned short to an object of the same underlying type complies with this rule (including use as a function argument or function return value), even though the conversion is implicit. Exampleuint8_t port = 0x5aU; uint8_t result_8; uint16_t result_16; uint16_t mode; result_8 = ( ~port ) >> 4; // Non-compliant '~port' is 0xffa5 on a 16-bit machine but 0xffffffa5 on a 32-bit machine. In either case the value of 'result' is 0xfa, but 0x0a may have been expected. This danger is avoided by inclusion of the cast as shown below: result_8 = ( static_cast< uint8_t > (~port) ) >> 4 ; // Compliant A similar problem exists when the '<<' operator is used on small integer types and high order bits are retained. For example: result_16 = ( ( port << 4 ) & mode ) >> 6; // Non-compliant The value in 'result_16' will depend on the implemented size of an int. Addition of a cast avoids any ambiguity. result_16 = ( static_cast < uint16_t > ( static_cast< uint16_t > ( port ) << 4 ) & mode ) >> 6; // Compliant Using intermediate steps would make this clearer: uint16_t port_16 = static_cast< uint16_t > ( port ); uint16_t port_shifted = static_cast< uint16_t > ( port_16 << 4 ); result_16 = ( port_shifted & mode ) >> 6; // Compliant |