Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Corrected typo, clarified, tweaked example.

Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int (see INT02-C. Understand integer conversion rules). If the conversion is to a wider type, the original value is zero-extended for unsigned values or zerosign-extended for signed types. Arithmetic operations performed on ints yield the same values as on chars and shorts (at least in the low-order bits). However, bitwise operations may have unexpected results.

...

Code Block
bgColor#FFcccc
uint8_t port = 0x5aU0x5a;
uint8_t result_8 = ( ~port ) >> 4;

In this example, a bitwise complement of port is negated, first computed and then shifted 4 bits to the right. If both of these operations were performed on a an 8-bit unsigned integer, then result_8 would have the value 0x0aU 0x0a. However, port will first be promoted to a 32-bit integer (signed or unsigned, depending on implementation) signed int, with the following results (on a typical architecture where type int is 32 bits wide):

Expression

Type

Value

Notes

port

uint8_t

0x5a

  0x0000005a

~port

int

0xffffffa5

 

~port >> 4

int

0x0ffffffa

Whether or not value is negative is implementation-defined.

result_8

uint8_t

0xfa

 

Compliant Solution

In this compliant solution, we truncate the negation back down to 8 bits. Consequently, result_8 receives the expected value of 0x0aU.

Code Block
bgColor#ccccff
uint8_t port = 0x5aU0x5a;
uint8_t result_8 = (uint8_t) (~port) >> 4;

...