Tcl Source Code

View Ticket
Login
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: