...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <limits.h>
signed int si_a;
signed int si_b;
signed int result;
void func(void) {
/* Initialize si_a, si_b and result */
if (((si_a^si_b) &
(((si_a ^ ((si_a^si_b) & INT_MIN)) -
si_b)^si_b)) < 0) {
/* Handle error condition */
} else {
result = si_a - si_b;
}
/* ... */
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <assert.h>
signed int si_a;
signed int si_b;
signed int result;
void func(void) {
/* Initialize si_a, si_b and result */
assert( UWIDTH( signed long long, ULLONG_MAX) >=
2 * UWIDTH( int, UINT_MAX));
signed long long 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 condition */
} else {
result = (int)tmp;
}
/* ... */
} |
The assertion fails if long long has less than twice the width of int. It relies on the UWIDTH() macro, which is defined in INT19-C.
...
Correctly compute integer widths.
On systems where this relationship does not existassertion would fail, the following compliant solution may be used to ensure signed overflow does not occur:
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <limits.h>
signed long s_a;
signed long s_b;
signed long result;
void func(void) {
/* Initialize s_a, s_b and result */
if ((s_b == 0 ) || ((s_a == LONG_MIN) && (s_b == -1))) {
/* Handle error condition */
} else {
result = s_a % s_b;
}
/* ... */
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <limits.h>
signed long s_a;
signed long result;
void func(void) {
if ((si1 < 0) || (si2 < 0) ||
(si2 >= UWIDTH(signed_int_width long, ULONG_MAX)) ||
(si1 > (INT_MAX >> si2))) {
/* handle error condition */
} else {
sresult = si1 << si2;
}
/* ... */
}
|
| Anchor | ||||
|---|---|---|---|---|
|
This The UWIDTH() macro provides the correct width for an unsigned integer type, and is defined in INT19-C. Correctly compute integer widths...see that rule for more information. This solution also complies with INT34-C. Do not shift a negative number of bits or more bits than exist in the operand. See that rule for how to compute the width of a signed int.
Atomic Integers
The C Standard defines the behavior of arithmetic on atomic signed integer types to use two's complement representation with silent wraparound on overflow; there are no undefined results. However, although defined, these results may be unexpected and therefore carry similar risks to unsigned integer wrapping (see INT30-C. Ensure that unsigned integer operations do not wrap). Consequently, signed integer overflow of atomic integer types should also be prevented or detected.
...