Ticket UUID: | 1241572 | |||
Title: | [expr] blind spot at corner of 32/64 bit integers | |||
Type: | Bug | Version: | None | |
Submitter: | nobody | Created on: | 2005-07-20 13:52:06 | |
Subsystem: | 11. Conversions from String | Assigned To: | kennykb | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2005-12-12 18:38:42 | |
Resolution: | Fixed | Closed By: | rmax | |
Closed on: | 2005-12-12 11:38:40 | |||
Description: |
% set x -2147483647; expr {abs($x)} 2147483647 % set x -2147483648; expr {abs($x)} integer value too large to represent % set x -2147483649; expr {abs($x)} 2147483649 This is a practical problem as we use -2147483648 (0x80000000, MIN_INT) to express missing data. Seen in 8.4.1 and 8.5a2 Tclkit, Windows XP and Linux. [email protected] | |||
User Comments: |
rmax added on 2005-12-12 18:38:42:
File Added - 159527: tcl-abs.patch rmax added on 2005-12-12 18:38:40: Logged In: YES user_id=124643 I just committed the attached patch to the 8.4 branch. It assumes that MIN_LONG is defined by one of the headers that are being included already. If there is any platform where this isn't true, a compatibility definition needs to be added. nobody added on 2005-12-12 17:38:51: Logged In: NO Hmm - my patch fixes 32bit platform, but it breaks 64bit :( How about using MIN_INT from limits.h for checking this special case, and providing compatibility definitions for platforms that don't have limits.h? rmax added on 2005-12-10 01:13:03: File Added - 159278: tcl-abs.patch rmax added on 2005-12-10 00:32:22: Logged In: YES user_id=124643 This fix depends on implementation defined behaviour of the compiler and fails with gcc 4.1.0. What happens is, that the compiler decides that the negation of a negative number can never have a negative result, and so it optimizes away the special case for INT_MIN as dead code. There are two solutions for this: either rewriting the code so that it doesn't depend on the assumption that -MIN_INT == MIN_INT, or use the -fwrapv parameter to gcc, so that it guarantees the wrapping behaviour of integers. See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25329 kennykb added on 2005-08-06 02:24:29: Logged In: YES user_id=99768 Right you are. Although in 8.4.11, you have to do expr {int(-2147483648)} to tickle the bug. Anyway, abs() is fixed. dkf added on 2005-07-20 21:05:29: Logged In: YES user_id=79902 Problem is it that it hits the "FIXME" case in ExprAbsFunc (in tclBasic.c in the HEAD.) |
Attachments:
- tcl-abs.patch [download] added by rmax on 2005-12-12 18:38:41. [details]