...
Code Block |
---|
|
#include <stddef.h>
#include <assert.h>
#include <limits.h>
#include <inttypes.h>
size_t popcount(uintmax_t num) {
size_t width = 0;
while (num != 0) {
if (num % 2 == 1) {
width++;
}
num >>= 1;
}
return width;
}
#define UWIDTH(type, umax_value) (sizeof(type) * CHAR_BITpopcount(umax_value)
void func(signed int si_a, signed int si_b) {
signed int result;
signed long long tmp;
assert(UWIDTH(signed long long, ULLONG_MAX) >=
2 * UWIDTH(int, UINT_MAX));
tmp = (signed long long)si_a * (signed long long)si_b;
/*
* If the product cannot be represented as a 32-bit integer,
* handle as an error condition.
*/
if ((tmp > INT_MAX) || (tmp < INT_MIN)) {
/* Handle error */
} else {
result = (int)tmp;
}
/* ... */
} |
The assertion fails if long long
has less than twice the width of int
. The purpose of the UWIDTH()
macro and the function popcount()
is explained in INT19-C. Correctly compute integer widths.
...
Code Block |
---|
|
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
extern size_t popcount(uintmax_t);
#define UWIDTH(type, umax_value) (sizeof(type) * CHAR_BITpopcount(umax_value)
void func(signed long si_a, signed long si_b) {
signed long result;
if ((si_a < 0) || (si_b < 0) ||
(si_b >= UWIDTH(signed long, ULONG_MAX)) ||
(si_a > (LONG_MAX >> si_b))) {
/* Handle error */
} else {
result = si1si_a << si2si_b;
}
/* ... */
}
|
Anchor |
---|
| Left Shift Operator |
---|
| Left Shift Operator |
---|
|
...