...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
extern size_t popcount(uintmax_t);
#define PRECISION(x) popcount(x)
void func(unsigned int ui_a, unsigned int ui_b) {
unsigned int uresult = 0;
if (ui_b >= PRECISION(UINT_MAX)) {
/* Handle error condition */
} else {
uresult = ui_a << ui_b;
}
/* ... */
} |
The
macro provides PRECISION()
macro and
popcount()
function provide the correct precision for any integer type (see INT35-C. Use correct integer precisions).
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h> #include <stddef.h> #include <inttypes.h> extern size_t popcount(uintmax_t); #define PRECISION(x) popcount(x) void func(signed long si_a, signed long si_b) { signed long result; if ((si_a < 0) || (si_b < 0) || (si_b >= PRECISION(ULONG_MAX)) || (si_a > (LONG_MAX >> si_b))) { /* Handle error */ } else { result = si_a << si_b; } /* ... */ } |
...
Noncompliant Code Example (Right Shift)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
extern size_t popcount(uintmax_t);
#define PRECISION(x) popcount(x)
void func(unsigned int ui_a, unsigned int ui_b) {
unsigned int uresult = 0;
if (ui_b >= PRECISION(UINT_MAX)) {
/* Handle error condition */
} else {
uresult = ui_a >> ui_b;
}
/* ... */
} |
The
macro provides the correct precision for any integer type (see INT35-C. Use correct integer precisions). PRECISION()
Implementation Details
GCC has no options to handle shifts by negative amounts or by amounts outside the width of the type predictably or to trap on them; they are always treated as undefined. Processors may reduce the shift amount modulo the width of the type. For example, 32-bit shifts are implemented using the following instructions on x86-32:
...