Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.CAST.UNSIGNED_BITS

The 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.

Example

uint8_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:

(a) immediately assigned to an object of the same underlying type as the operand;
(b) used as a function argument of the same underlying type as the operand;
(c) used as a return expression of a function whose return type is of the same underlying type as the operand.

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.

Rationale

When 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.

Exception

The 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.

Example

uint8_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