...
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 / 2 E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined and may be either an arithmetic (signed) shift as shown below or a logical (unsigned) shift.
This non-compliant code example fails to prevent to test if the right operand negative or is greater than or equal to the width of the promoted left operand, allowing undefined behavior.
| Code Block | ||
|---|---|---|
| ||
int si1, si2, sresult; unsigned int ui1, ui2, uresult; sresult = si1 >> si2; uresult = ui1 >> ui2; |
...
| Code Block | ||
|---|---|---|
| ||
int si1, si2, sresult; unsigned int ui1, ui2, result; if ( (si1 < 0) || (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) ) { /* handle error condition */ } else { sresult = si1 >> si2; } if (ui2 >= sizeof(unsigned int)*CHAR_BIT) { /* handle error condition */ } else { uresult = ui1 >> ui2; } |
As already noted, if the left operand has a signed type and a negative value, the resulting right shift could be either an arithmetic (signed) shift or a logical (unsigned) shift. For implementations in which an arithmetic shift is performed, and the sign bit can be propagated as the number is shifted.
| Code Block | ||
|---|---|---|
| ||
int stringify;
char buf[sizeof("256")];
sprintf(buf, "%u", stringify >> 24);
|
If stringify has the value 0x80000000, stringify>> 24 evaluates to 0xFFFFFF80 and the subsequent call to sprintf() results in a buffer overflow.
For bit extraction, one remediation is to use the idiom ((number >> 24) & 0xff).
Exceptions
Unsigned integers can be allowed to exhibit modulo behavior if and only if
...
| Wiki Markup |
|---|
\[[Dowd 06|AA. C References#Dowd 06]\] Chapter 6, "C Language Issues"
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.5.7, "Bitwise shift operators"
\[[Seacord 05|AA. C References#Seacord 05]\] Chapter 5, "Integers"
\[[Viega 05|AA. C References#Viega 05]\] Section 5.2.7, "Integer overflow"
\[[ISO/IEC 03|AA. C References#ISO/IEC 03]\] Section 6.5.7, "Bitwise shift operators" |