Mercurial > gnulib
changeset 18780:324d6f3d7b3f
intprops: improve comments
* lib/intprops.h: Improve and shorten commentary.
For the record, if we ever run into a pedantic compiler that
behaves differently from GCC when converting an out-of-range value
to a signed integer, we can work around the problem with something
like the following code, where UCT is the signed counterpart of T
(UCT is sometimes narrower than UT) and all callers are changed
accordingly:
((t) ((ut) (a) op (ut) (b)))
(TYPE_MINIMUM (t) <= (uct) ((ut) (a) op (ut) (b)) \
? ((t) (uct) (((ut) (a) op (ut) (b)) - TYPE_MINIMUM (t)) \
+ TYPE_MINIMUM (t)) \
: (t) (uct) ((ut) (a) op (ut) (b)))
author | Paul Eggert <eggert@Penguin.CS.UCLA.EDU> |
---|---|
date | Sat, 15 Apr 2017 14:27:11 -0700 |
parents | 7e8aab3a79b6 |
children | 873ea29f4b3b |
files | ChangeLog lib/intprops.h |
diffstat | 2 files changed, 34 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Apr 14 19:03:20 2017 -0700 +++ b/ChangeLog Sat Apr 15 14:27:11 2017 -0700 @@ -1,3 +1,24 @@ +2017-04-15 Paul Eggert <eggert@Penguin.CS.UCLA.EDU> + + intprops: improve comments + * lib/intprops.h: Improve and shorten commentary. + For the record, if we ever run into a pedantic compiler that + behaves differently from GCC when converting an out-of-range value + to a signed integer, we can work around the problem with something + like the following code, where UCT is the signed counterpart of T + (UCT is sometimes narrower than UT) and all callers are changed + accordingly: + #if __SUNPRO_C <= 0x5120 + # define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, uct, ut, t) \ + ((t) ((ut) (a) op (ut) (b))) + #else + # define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, uct, ut, t) \ + (TYPE_MINIMUM (t) <= (uct) ((ut) (a) op (ut) (b)) \ + ? ((t) (uct) (((ut) (a) op (ut) (b)) - TYPE_MINIMUM (t)) \ + + TYPE_MINIMUM (t)) \ + : (t) (uct) ((ut) (a) op (ut) (b))) + #endif + 2017-04-14 Paul Eggert <eggert@Penguin.CS.UCLA.EDU> intprops: try to avoid tickling similar bugs
--- a/lib/intprops.h Fri Apr 14 19:03:20 2017 -0700 +++ b/lib/intprops.h Sat Apr 15 14:27:11 2017 -0700 @@ -444,29 +444,22 @@ ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) -/* Return A <op> B, where the operation is given by OP. Return the - low-order bits of the mathematically-correct answer. Use the - unsigned type UT for calculation to avoid undefined behavior on - signed integer overflow. Assume that conversion to the result type - T yields the low-order bits in the usual way. UT is at least as - wide as T and is no narrower than unsigned int, T is two's - complement, and there is no padding or trap representations. +/* Return the low-order bits of A <op> B, where the operation is given + by OP. Use the unsigned type UT for calculation to avoid undefined + behavior on signed integer overflow, and convert the result to type T. + UT is at least as wide as T and is no narrower than unsigned int, + T is two's complement, and there is no padding or trap representations. + Assume that converting UT to T yields the low-order bits, as is + done in all known two's-complement C compilers. E.g., see: + https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html According to the C standard, converting UT to T yields an - implementation-defined result or signal for values outside T's range. - So, the standard way to convert UT to T is to subtract TMIN from - greater-than-TMAX values before converting them to T, and to add - TMIN afterwards, where TMIN and TMAX are T's extrema. - However, in practice there is no need to subtract and add TMIN. - E.g., GCC converts to signed integers in the usual way; see: - https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html - All other known C compilers are similar to GCC in this respect. - Furthermore, Oracle Studio 12.3 x86 has a bug when implementing the - standard way; see: + implementation-defined result or signal for values outside T's + range. However, code that works around this theoretical problem + runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html - - So, implement this operation in the usual way rather than in - the standard way. */ + As the compiler bug is real, don't try to work around the + theoretical problem. */ #define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ ((t) ((ut) (a) op (ut) (b)))