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