Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: unsigned left shift NCCE/CS in INT34-C before signed, because it is simpler

...

In almost every case, an attempt to shift by a negative number of bits or by more than the precision of the operand indicates a bug (logic error). A logic error is different from overflow, in which there is simply a representational deficiency.  In general, shifts should only be performed on unsigned operands (see INT13-C. Use bitwise operators only on unsigned operands).

Noncompliant Code Example (Left Shift, Unsigned Type)

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. The following diagram illustrates the left shift operation:

Image Added

According to the C Standard, if E1 has an unsigned type, the value of the result is E1 * 2E2, reduced modulo 1 more than the maximum value representable in the result type. 

This noncompliant code example fails to ensure that the right operand is less than or equal to the precision of the promoted left operand:

Code Block
bgColor#FFcccc
langc
void func(unsigned int ui_a, unsigned int ui_b) {
  unsigned int uresult = ui_a << ui_b;
  /* ... */
}

Compliant Solution (Left Shift, Unsigned Type)

This compliant solution eliminates the possibility of shifting by more bits than exist in the left hand operand:

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>

extern size_t popcount(uintmax_t);
#define PRECISION(x) popcount(x)
 
void func(unsigned int ui_a, unsigned int ui_b) {
  unsigned int uresult = 0;
  if (ui_b >= PRECISION(UINT_MAX)) {
    /* Handle error condition */
  } else {
    uresult = ui_a << ui_b;
  }

  /* ... */
}

Modulo behavior resulting from left-shifting an unsigned integer type is permitted by exception INT30-EX3 to INT30-C. Ensure that unsigned integer operations do not wrap.

Noncompliant Code Example (Left Shift, Signed Type)

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has a signed type and nonnegative value and E1 * 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

Image Removed

This noncompliant code example fails to ensure that left and right operands have nonnegative values and that the right operand is less than or equal to the precision of the promoted left operand. This example does check for signed integer overflow in compliance with INT32-C. Ensure that operations on signed integers do not result in overflow.

...

The PRECISION()macro provides the correct precision for any integer type (see INT35-C. Use correct integer precisions)

Noncompliant Code Example (Left Shift, Unsigned Type)

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. According to the C Standard, if E1 has an unsigned type, the value of the result is E1 * 2E2, reduced modulo 1 more than the maximum value representable in the result type.

This noncompliant code example fails to ensure that the right operand is less than or equal to the precision of the promoted left operand:

Code Block
bgColor#FFcccc
langc
void func(unsigned int ui_a, unsigned int ui_b) {
  unsigned int uresult = ui_a << ui_b;
  /* ... */
}

Compliant Solution (Left Shift, Unsigned Type)

This compliant solution eliminates the possibility of shifting by more bits than exist in the left hand operand:

...

...

 

...

Modulo behavior resulting from left-shifting an unsigned integer type is permitted by exception INT30-EX3 to INT30-C. Ensure that unsigned integer operations do not wrap.

Noncompliant Code Example (Right Shift)

...