Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: took out CCE on signed ints, since that violates INT13-C.

...

Code Block
bgColor#FFcccc
int si1;
int si2;
int sresult;

sresult = si1 << si2;

Compliant Solution (Left Shift, Signed Type)

This compliant solution eliminates the possibility of undefined behavior resulting from a left shift operation on integers. It also uses unsigned integers Do not apply shift oprators to signed types, in accordance with INT13-C. Use bitwise operators only on unsigned operands. Smaller sized integers are promoted according to the integer promotion rules (see INT02-C. Understand integer conversion rules).

Code Block
bgColor#ccccff

unsigned int ui1;
unsigned int ui2;
unsigned int sresult;

if ((ui2 >= sizeof(int)*CHAR_BIT)
  || (ui1 > (INT_MAX >> ui2)) )
{
  /* handle error condition */
}
else {
  sresult = ui1 << ui2;
}

In C99, the CHAR_BIT macro defines the number of bits for the smallest object that is not a bit-field (byte). Consequently, a byte contains CHAR_BIT bits.

Noncompliant Code Example (Left Shift, Unsigned Type)

...

Code Block
bgColor#ccccff
unsigned int ui1
unsigned int ui2
unsigned int uresult;

/* modulo behavior is allowed on mod1 and mod2 by exception */
unsigned int mod1
unsigned int mod2;

/* ... */

if ( (ui2 >= sizeof(unsigned int)*CHAR_BIT)
  || (ui1 > (UINT_MAX  >> ui2))) )
 {
  /* handle error condition */
}
 else {
  uresult = ui1 << ui2;
}

if (mod2 >= sizeof(unsigned int)*CHAR_BIT) {
  /* handle error condition */
}
 else {
  /* modulo behavior is allowed by exception */
  uresult = mod1 << mod2;
}

...

Even though this noncompliant code example explicitly declares the operands to a right shift as unsigned (see INT13-C. Use bitwise operators only on unsigned operands), it fails to test whether the right operand is negative or is greater than or equal to the width of the promoted left operand, allowing undefined behavior.

...