...
This noncompliant code example can result in undefined behavior because there is no check to ensure that left and right operands have nonnegative values and that the right operand is less than or equal to the width of the promoted left operand:. The example can also produce signed integer overflow; see INT32-C. Ensure that operations on signed integers do not result in overflow for more information.
Code Block | ||||
---|---|---|---|---|
| ||||
void func(intsigned long si_a, signed intlong si_b) { intsigned long sresult = si_a << si_b; /* ... */ } |
Shift operators and other bitwise operators should be used only with unsigned integer operands in accordance with INT13-C. Use bitwise operators only on unsigned operands.
Compliant Solution (Left Shift, Signed Type)
This compliant solution eliminates the possibility of overflow resulting from a left-shift operation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
void func(signed long si_a, signed long si_b) {
signed long result;
if ((si_a < 0) || (si_b < 0) ||
(si_b >= UWIDTH(ULONG_MAX)) ||
(si_a > (LONG_MAX >> si_b))) {
/* Handle error */
} else {
result = si_a << si_b;
}
/* ... */
}
|
The UWIDTH()
macro provides the correct width for an unsigned integer type (see INT19-C. Correctly compute integer widths). This solution also complies with INT34-C. Do not shift a negative number of bits or more bits than exist in the operand.
Noncompliant Code Example (Left Shift, Unsigned Type)
...