From: Kristian Nielsen
Date: October 27 2007 9:37am
Subject: Re: bk commit into 5.0 tree (knielsen:1.2488) BUG#31799
List-Archive: http://lists.mysql.com/commits/36477
Message-Id: <87640s6gpd.fsf@mysql.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Sergei Golubchik writes:
> On Oct 24, knielsen@stripped wrote:
>> ChangeSet@stripped, 2007-10-24 09:26:25+02:00, knielsen@ymer.(none) +4 -0
>> BUG#31799: Scrambled number output due to integer overflow
>>=20=20=20
>> An integer overflow in number->string conversion caused completely
>> wrong output of the number LONGLONG_MIN with gcc 4.2.1.
>>=20=20=20
>> Fixed by eliminating the overflow, using only operations that are
>> well-defined in ANSI C.
>
> Where does the standard say that the result is undefined ?
> I wasn't able to find it :(
My (old, second edition) of Stroustrups C++ book says in the reference manu=
al,
r.5:
"The handling of overflow and divide check in expression evaluation is
implementation dependent."
and in r.3.6.1:
"Unsigned integers ... obey the laws of arithmetic modulo 2**n ... This
implies that unsigned arithmetic does not overflow."
For ANSI C, my Kernighan and Ritchie says in the reference manual A7 (my
translation back to English from a poorly translated Danish edition):
"Handling of overflow, division control, and other exceptions in
expression evaluation is not defined in the laguage."
and in A4.2:
"Unsigned integers ... obey the laws of arithmetic modulo 2**n ... so
therefore arithmetic on an unsigned value never overflows."
> Regards / Mit vielen Gr=C3=BCssen,
> Sergei
Thanks for reviewing, btw. GCC is doing some really interesting optimizatio=
ns
in that code. It is combining the two loops into one, apparently realising
that they are exactly the same except for type sizes. And I *think* what is
happening is that in the (val < 0) case, GCC realises that the loop will
always be run at least once, so it unrolls the first iteration of the loop,
skipping the first loop check, and also in the first iteration divides by -=
10
instead of 10 to avoid having to do the negation of val. I guess it is this
last divide by negative number that causes overflow problems for LONGLONG_M=
IN.
(and btw it does the constant divisions by multiplication of the correspond=
ing
fraction using fixed-point arithmetics I believe).
But as far as I can see, it _seems_ that GCC is not violating any of the C
standard...
- Kristian.