signed integer overflow
Bob Tennent
rdt@cs.queensu.ca
Tue Feb 6 07:06:00 GMT 2001
Not really a bug, but in my opinion a serious deficiency. It seems there is
no efficient way to detect a signed integer overflow, apart from using inline
assembler. I realize the C standard allows a compiler to do what it wants, but
surely the sensible thing to do is to set a testable flag and/or provide an
option to abort on overflow.
I attach a newsgroup exchange that may be of interest.
Bob T.
________________________________________________________________________________
From torvalds@penguin.transmeta.com Tue Feb 6 09:36:41 2001
From: torvalds@penguin.transmeta.com (Linus Torvalds)
Newsgroups: comp.os.linux.development.apps
Subject: Re: Overflow detection in gcc-produced code?
In article <slrn97tsgd.pu3.BobT@linus.cs.queensu.ca>,
Bob Tennent <rdtennent@hotmail.com> wrote:
>Is there any way to detect that an overflow has occurred in x86 integer
>arithmetic code produced by gcc?
unsigned long x, y, sum;
int overflow = 0;
sum = x+y;
if (sum < x)
overflow = 1;
Works portably in C (but only with "unsigned" types that are guaranteed
to have twos-complement behaviour and well-defined overflow semantics).
And good compilers will notice that "overflow" is really just the carry
flag, and optimize it. I don't remember if gcc counts as "good" in this
case, but I doubt it ;)
For signed integer arithmetic, you're basically screwed. A compiler is
in theory allowed to do anything at all for signed overflows, so you
cannot portably test the result at all: you have to detect the overflow
before the operation happens. In practice, of course, all x86 compilers
will just result in the "proper" overflow value, but you still have to
test whether an overflow occurred.
At some point it probably becomes easier to do it with inline asm.
Especially if it needs to be efficient. One (inefficient) way might be
to do the calculation in "long long" and do a
long long x, y, sum;
in toverflow = 0;
sum = x + y;
if (sum != (long)sum)
overflow = 1;
but if you look at the actual code it generates, you'll be really sad.
Linus
From berkes@pc9.CutThis.org Tue Feb 6 09:36:19 2001
From: Jem Berkes <berkes@pc9.CutThis.org>
Linus Torvalds wrote:
>
> In article <slrn97tsgd.pu3.BobT@linus.cs.queensu.ca>,
> Bob Tennent <rdtennent@hotmail.com> wrote:
> >Is there any way to detect that an overflow has occurred in x86 integer
> >arithmetic code produced by gcc?
>
> unsigned long x, y, sum;
> int overflow = 0;
>
> sum = x+y;
> if (sum < x)
> overflow = 1;
Gosh, what can I say in follow-up to the great one? ;)
Not that I've done any assembler stuff within gcc, but if there's some
way to embed x86 assembler in there you can also use the "JO" mnemonic
(jump if overflow), e.g.
jo overflow
jmp no_of
:overflow
; what to do now?
:no_of
; jump here if no overflow
From berkes@pc9.CutThis.org Tue Feb 6 09:36:59 2001
From: Jem Berkes <berkes@pc9.CutThis.org>
Jem Berkes wrote:
>
> jo overflow
> jmp no_of
> :overflow
> ; what to do now?
> :no_of
> ; jump here if no overflow
Ick, that was messy. Try again, using "jump if not overflow" (JNO)
jno no_of
// handle overflow
:no_of
// finished
More information about the Gcc-bugs
mailing list