autoconf: Signed Overflow Advice
1
1 13.2.4 Practical Advice for Signed Overflow Issues
1 --------------------------------------------------
1
1 Ideally the safest approach is to avoid signed integer overflow
1 entirely. For example, instead of multiplying two signed integers, you
1 can convert them to unsigned integers, multiply the unsigned values,
1 then test whether the result is in signed range.
1
1 Rewriting code in this way will be inconvenient, though,
1 particularly if the signed values might be negative. Also, it may hurt
1 performance. Using unsigned arithmetic to check for overflow is
1 particularly painful to do portably and efficiently when dealing with an
1 integer type like `uid_t' whose width and signedness vary from platform
1 to platform.
1
1 Furthermore, many C applications pervasively assume wraparound
1 behavior and typically it is not easy to find and remove all these
1 assumptions. Hence it is often useful to maintain nonstandard code
1 that assumes wraparound on overflow, instead of rewriting the code.
1 The rest of this section attempts to give practical advice for this
1 situation.
1
1 If your code wants to detect signed integer overflow in `sum = a +
1 b', it is generally safe to use an expression like `(sum < a) != (b <
1 0)'.
1
1 If your code uses a signed loop index, make sure that the index
1 cannot overflow, along with all signed expressions derived from the
1 index. Here is a contrived example of problematic code with two
1 instances of overflow.
1
1 for (i = INT_MAX - 10; i <= INT_MAX; i++)
1 if (i + 1 < 0)
1 {
1 report_overflow ();
1 break;
1 }
1
1 Because of the two overflows, a compiler might optimize away or
1 transform the two comparisons in a way that is incompatible with the
1 wraparound assumption.
1
1 If your code uses an expression like `(i * 2000) / 1000' and you
1 actually want the multiplication to wrap around on overflow, use
1 unsigned arithmetic to do it, e.g., `((int) (i * 2000u)) / 1000'.
1
1 If your code assumes wraparound behavior and you want to insulate it
1 against any GCC optimizations that would fail to support that behavior,
1 you should use GCC's `-fwrapv' option, which causes signed overflow to
1 wrap around reliably (except for division and remainder, as discussed
1 in the next section).
1
1 If you need to port to platforms where signed integer overflow does
1 not reliably wrap around (e.g., due to hardware overflow checking, or to
1 highly aggressive optimizations), you should consider debugging with
1 GCC's `-ftrapv' option, which causes signed overflow to raise an
1 exception.
1