Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added discussion bout computing width in types with padding bits

...

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 of unsigned int */
  if (ui_b >= sizeof(unsigned int)*CHAR_BITwidth) {
    /* 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 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;
}

Noncompliant Code Example (Right 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 */
  if (ui_b >= sizeof(size_t width = /* width of unsigned int) * CHAR_BIT/
  if (ui_b >= width) {
    /* Handle error condition */
  } else {
    uresult = ui_a >> ui_b;
  }
  /* ... */
}

...