Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: xref INT19-C

...

Code Block
bgColor#ccccff
langc
unsigned int ui_a;
unsigned int ui_b;
unsigned int uresult;

void func(void) {
  /* Initialize ui_a and ui_b */
  size_t width = /* width ofif (ui_b >= UWIDTH( unsigned int */
  if (ui_b >= width, UINT_MAX)) {
    /* Handle error condition */
  } else {
    uresult = ui_a << ui_b;
  }

  /* ... */
}

Modulo behavior resulting from left-shifting an unsigned integer type is permitted by this standard.

The computation of UWIDTH() macro provides the correct width of any integer type can be nontrivial. On machines with no padding bits, the width can be computed directly from the integer's size:

Code Block
bgColor#ccccff
langc
size_t width = sizeof(unsigned int) * CHAR_BIT;

Some platforms provide a population count operation, which counts the number of bits that are set. This can be used to compute the width:

Code Block
bgColor#ccccff
langc
size_t width = _popcount(UINT_MAX);

For other platforms, you can implement _popcount yourself:

Code Block
bgColor#ccccff
langc
unsigned int val = UINT_MAX;
size_t width = 0;
while (val != 0) {
  width++;
  val >>= 1;
}

for an unsigned integer type, and is defined in INT19-C. Correctly compute integer widths...see that rule for more information.

Noncompliant Code Example (Right Shift)

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined and can be either an arithmetic (signed) shift:

...

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
unsigned int ui_a;
unsigned int ui_b;
unsigned int uresult;

void func(void) {
  /* Initialize ui_a and ui_b */
  size_t width = /* width of if (ui_b >= UWIDTH( unsigned int */
  if (ui_b >= width, UINT_MAX)) {
    /* Handle error condition */
  } else {
    uresult = ui_a >> ui_b;
  }
  /* ... */
}

 

The UWIDTH() macro provides the correct width for an unsigned integer type, and is defined in INT19-C. Correctly compute integer widths...see that rule for more information.

Implementation Details

GCC has no options to handle shifts by negative amounts or by amounts outside the width of the type predictably or trap on them; they are always treated as undefined. Processors may reduce the shift amount modulo the width of the type. For example, 32-bit shifts are implemented using the following instructions on IA-32:

...