...
Code Block | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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.
...