...
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.
...