MISRA Discussion Forums

Full Version: Rule 10.5, shift left operator example
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
While the issue about the ~ operator in rule 10.5 is obviously handled by an immediate cast, I've been wondering, what the immediate cast of a shift left (
I suppose they are hinting between the lines that the 16 bit "mode" variable could contain values in the upper byte.
These are the declarations from the example:

uint8_t port = 0x5aU;
uint16_t mode;

First you take 0x5A left shift 4. The integer promotions will make "port" int, with the contents 0x5A0. Since the shift is performed on a 16 bit integer (or larger), nothing is shifted out.
Then you do bitwise AND with "mode". If "mode" contains anything in the higher byte, there is a potential for garbage values. Lets say that "mode" has the value 0xFFFF. Then all values in the upper byte are preserved, and the result will be 0x5A0 >> 6, giving 0x16 rather than as perhaps expected, 0xA0 >> 6 giving 0x02.

With an explicit cast (uint8_t)(port
Dear Lundin, thanks for your response.

If in the example the shift result were cast to uint8_t, it would be at least consistent to the rule (cast to the underlying type). But then in most cases, the very cast then would prevent what the programmer actually intended. So I'm a bit at a loss with the question, if rule 10.5 in general could be meaningful at all in the context of the
I tried to give you one example where it would happen, based on the one from MISRA.

This code will give incorrect result:

Code:
#define MASK 0x01U

  uint8_t  port = 0x5AU;
  uint16_t mode;
  uint16_t result_16;
  
  mode = ~MASK;   /* here the programmer gets values in the upper byte without realizing it */
  
  result_16 = ((port > 6; /* strange result */

And this will fix it:

result_16 = ((uint8_t)(port > 6;
The purpose of Rule 10.5 is to remove ambiguity and any dependency on the size of int when performing bitwise shift and bitwise complement operations.

There are clearly situations where addition of a cast might seem unnecessary. However it is unfortunately true that the great majority of C developers do not understand the mechanism of integral promotion and imposition of this rule is intended to provide some protection against ignorance.

With reference to the specific example, it does appear that the value is independent of the size of the implemented int type and that the explanatory text is therefore incorrect. However, the value of a similar expression with different types (uint_16 instead of uint_8 for example) or with different shift constants would depend on the int type. Therefore, in general the comment applies even if not to this particular example.

Tracker ID: 0000016