autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Autoconf manual's coverage of signed integer overflow & portability


From: Paul Eggert
Subject: Re: Autoconf manual's coverage of signed integer overflow & portability
Date: Tue, 02 Jan 2007 23:21:31 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Here are further patches I checked into the Autoconf documentation to
reflect today's comments (some of which I received privately).  Thanks
to all of you.  The trickiest bit was documenting one simple way to
reliably detect overflow without converting to unsigned and back.
(At least, I hope it's reliable....)

2007-01-02  Paul Eggert  <address@hidden>

        * doc/autoconf.texi (Integer Overflow): Revised based on today's
        feedback.  The most important changes document what happens when
        you convert an out-of-range value to a signed integer type, and
        say that (sum < a) != (b < 0) reliably detects overflow when sum =
        a + b.

--- doc/autoconf.texi   2 Jan 2007 23:06:07 -0000       1.1122
+++ doc/autoconf.texi   3 Jan 2007 07:18:35 -0000
@@ -14954,12 +14954,12 @@ the programs work well enough in practic
 @cindex signed integer overflow
 @cindex wraparound arithmetic

-Many portable C programs assume that signed integer overflow wraps
+In practice many portable C programs assume that signed integer overflow wraps
 around reliably using two's complement arithmetic.  Yet the C standard
 says that program behavior is undefined on overflow, and in a few cases
 C programs do not work on some modern implementations because their
-overflows do not wrap around as their authors intended.  Conversely, in
-at least one common case related to overflow, the C standard requires
+overflows do not wrap around as their authors expected.  Conversely, in
+signed integer remainder, the C standard requires overflow
 behavior that is commonly not implemented.

 @menu
@@ -14977,9 +14977,11 @@ behavior that is commonly not implemente
 @cindex signed integer overflow
 @cindex wraparound arithmetic

-In languages like C, unsigned integer overflow reliably wraps around
-modulo the word size.  This is guaranteed by the C standard and is
-portable in practice, unless you specify aggressive optimization options
+In languages like C, unsigned integer overflow reliably wraps around;
+e.g., @code{UINT_MAX + 1} yields zero.
+This is guaranteed by the C standard and is
+portable in practice, unless you specify aggressive,
+nonstandard optimization options
 suitable only for special applications.

 In contrast, the C standard says that signed integer overflow leads to
@@ -15000,6 +15002,12 @@ For historical reasons the C standard al
 ones' complement or signed magnitude arithmetic, but it is safe to
 assume two's complement nowadays.

+Also, overflow can occur when converting an out-of-range value to a
+signed integer type.  Here a standard implementation must define what
+happens, but this might include raising an exception.  In practice all
+known implementations support silent wraparound in this case, so you need
+not worry about other possibilities.
+
 @node Signed Overflow Examples
 @subsection Examples of Code Assuming Wraparound Overflow
 @cindex integer overflow
@@ -15038,7 +15046,7 @@ and generate code that allows superuser 
 Despite this requirement by the standard, it has long been common for C
 code to assume wraparound arithmetic after signed overflow, and all
 known practical C implementations support some C idioms that assume
-wraparound signed arithmetic, even if the idioms does not conform
+wraparound signed arithmetic, even if the idioms do not conform
 strictly to the standard.  If your code looks like the following
 examples it will almost surely work with real-world compilers.

@@ -15060,7 +15068,7 @@ signed overflow when computing the most 
 overflows) or a value near an extreme integer (the first @code{+}
 overflows).

-Here is another example, taken from the 7th Edition implementation of
+Here is another example, derived from the 7th Edition implementation of
 @code{rand} (1979-01-10).  Here the programmer expects both
 multiplication and addition to wrap on overflow:

@@ -15186,7 +15194,7 @@ can convert them to unsigned integers, m
 then test whether the result is in signed range.

 Rewriting code in this way will be inconvenient, though, particularly if
-the signed values might be negative.  Also, it will probably hurt
+the signed values might be negative.  Also, it may hurt
 performance.  Using unsigned arithmetic to check for overflow is
 particularly painful to do portably and efficiently when dealing with an
 integer type like @code{uid_t} whose width and signedness vary from
@@ -15198,6 +15206,10 @@ Hence it is often useful to maintain non
 wraparound on overflow, instead of rewriting the code.  The rest of this
 section attempts to give practical advice for this situation.

+If your code wants to detect signed integer overflow in @code{sum = a +
+b}, it is generally safe to use an expression like @code{(sum < a) != (b
+< 0)}.
+
 If your code uses a signed loop index, make sure that the index cannot
 overflow, along with all signed expressions derived from the index.
 Here is a contrived example of problematic code with two instances of
@@ -15218,9 +15230,8 @@ transform the two comparisons in a way t
 wraparound assumption.

 If your code uses an expression like @code{(i * 2000) / 1000} and you
-actually want the multiplication to wrap around reliably, put the
-product into a temporary variable and divide that by 1000.  This
-inhibits the algebraic optimization on many platforms.
+actually want the multiplication to wrap around, use unsigned arithmetic
+to do it, e.g., @code{((int) (i * 2000u)) / 1000}.

 If your code assumes wraparound behavior and you want to insulate it
 against any @acronym{GCC} optimizations that would fail to support that




reply via email to

[Prev in Thread] Current Thread [Next in Thread]