Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > check integer overflow with GCC 4.5.2

Reply
Thread Tools

check integer overflow with GCC 4.5.2

 
 
sailer
Guest
Posts: n/a
 
      11-24-2011
Hi,

I have the following code which was used to check whether the result
of (a * b) is larger than the maximum integer value.

ovf(int a, int b, int *r, int *v)
{
*r = a * b;
if (b == 0 || a == *r / b)
*v = 0;
else
*v = 1;

}

int main()
{
int words;
int bytes;
int overflow;

//... whatever
ovf(words, sizeof(int), &bytes, &overflow);
if (overflow)
printf("overflow");

}

It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
generated by GCC is as follows, call to ovf is eliminated, seems
that
GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
to
revise ovf to let it satisfy GCC? thanks in advance.

main:
pushl %ebp #
xorl %eax, %eax #
movl %esp, %ebp #,
popl %ebp #
ret
.size main, .-main
.ident "GCC: (GNU) 4.5.2"
.section .note.GNU-stack,"",@progbits
 
Reply With Quote
 
 
 
 
Tobias Müller
Guest
Posts: n/a
 
      11-24-2011
sailer <(E-Mail Removed)> wrote:
> Hi,
>
> I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.
>
> ovf(int a, int b, int *r, int *v)
> {
> *r = a * b;
> if (b == 0 || a == *r / b)
> *v = 0;
> else
> *v = 1;
>
> }
>
> int main()
> {
> int words;
> int bytes;
> int overflow;
>
> //... whatever
> ovf(words, sizeof(int), &bytes, &overflow);
> if (overflow)
> printf("overflow");
>
> }
>
> It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> generated by GCC is as follows, call to ovf is eliminated, seems
> that
> GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> to
> revise ovf to let it satisfy GCC? thanks in advance.
>
> main:
> pushl %ebp #
> xorl %eax, %eax #
> movl %esp, %ebp #,
> popl %ebp #
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.5.2"
> .section .note.GNU-stack,"",@progbits


The possibility of such optimizations is one reasons, why int overflow is
undefined behaviour.

The correctly formulated question (compiler neutral) would then be how to
implement this test without relying on UB. (some people on this list are a
bit picky about that)

You could take unsigned int instead, where overflow is defined:

ovf(int a, int b, unsigned int *r, int *v)
{
*r = (unsigned int)a * b;
if (b == 0 || (a == *r / b && r <= INT_MAX))
*v = 0;
else
*v = 1;
}

This is just to illustrate, notice however that:
- this is really C rather than C++
- it does not work for underflows
- it probably leads to compiler warnings without some more casts
- I have not tested it.
- there are probably more efficient ways of achieving the same thing

Tobi
 
Reply With Quote
 
 
 
 
sailer
Guest
Posts: n/a
 
      11-24-2011
On Nov 24, 2:46*pm, Tobias Mller <(E-Mail Removed)> wrote:
> sailer <(E-Mail Removed)> wrote:
> > Hi,

>
> > I have the following code which was used to check whether *the result
> > *of (a * b) *is larger than the maximum integer value.

>
> > ovf(int a, int b, int *r, int *v)
> > *{
> > * * * * **r = a * b;
> > * * * * *if (b == 0 || a == *r / b)
> > * * * * * * * * **v = 0;
> > * * * * *else
> > * * * * * * * * **v = 1;

>
> > }

>
> > int main()
> > *{
> > * * *int words;
> > * * *int bytes;
> > * * *int overflow;

>
> > * * //... whatever
> > * * *ovf(words, sizeof(int), &bytes, &overflow);
> > * * *if (overflow)
> > * * * * printf("overflow");

>
> > }

>
> > It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> > *generated by GCC is as follows, call to ovf is eliminated, seems
> > that
> > *GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> > to
> > *revise ovf to let it satisfy GCC? thanks in advance.

>
> > main:
> > * * * * *pushl * %ebp * *#
> > * * * * *xorl * *%eax, %eax * * *#
> > * * * * *movl * *%esp, %ebp * * *#,
> > * * * * *popl * *%ebp * *#
> > * * * * *ret
> > * * * * *.size * main, .-main
> > * * * * *.ident *"GCC: (GNU) 4.5.2"
> > * * * * *.section * * * *.note.GNU-stack,"",@progbits

>
> The possibility of such optimizations is one reasons, why int overflow is
> undefined behaviour.
>
> The correctly formulated question (compiler neutral) would then be how to
> implement this test without relying on UB. (some people on this list are a
> bit picky about that)
>
> You could take unsigned int instead, where overflow is defined:
>
> ovf(int a, int b, unsigned int *r, int *v)
> {
> * * * * * *r = (unsigned int)a * b;
> * * * * * if (b == 0 || (a == *r / b && r <= INT_MAX))
> * * * * * * * * * *v = 0;
> * * * * * else
> * * * * * * * * * *v = 1;
>
> }
>
> This is just to illustrate, notice however that:
> - this is really C rather than C++
> - it does not work for underflows
> - it probably leads to compiler warnings without some more casts
> - I have not tested it.
> - there are probably more efficient ways of achieving the same thing
>
> Tobi



Tobi,

Really appreciate your replying, it helps much in understanding the
background of the problem.
I gave a try to use unsigned and INT_MAX but failed to address the
issue, happened to find
add "__attribute__ ((noinline))" before ovf solves it.
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      11-24-2011
On Thu, 2011-11-24, sailer wrote:
> Hi,
>
> I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.

....

You posted the same(?) question to comp.lang.c. Please don't do it that
way; it wastes people's time. Cross-post instead of multi-post.

regards,
/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Tobias Müller
Guest
Posts: n/a
 
      11-24-2011
sailer <(E-Mail Removed)> wrote:
> Tobi,
>
> Really appreciate your replying, it helps much in understanding the
> background of the problem.
> I gave a try to use unsigned and INT_MAX but failed to address the
> issue, happened to find
> add "__attribute__ ((noinline))" before ovf solves it.


It solves it for now, but compilers will become better and your problem
will reappear...

The optimization can also be applied without inlining, it's just that the
compiler missed that opportunity.

If you are interested, here is a link to a good article about UB on the
llvm/clang compiler Blog (actually a serie 3 articles). It also covers your
case (integer overflow).
http://blog.llvm.org/2011/05/what-ev...ould-know.html

Tobi
 
Reply With Quote
 
Fred Zwarts \(KVI\)
Guest
Posts: n/a
 
      11-25-2011
"sailer" wrote in message
news:(E-Mail Removed)...
>
>Hi,
>
>I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.
>
>ovf(int a, int b, int *r, int *v)
> {
> *r = a * b;
> if (b == 0 || a == *r / b)
> *v = 0;
> else
> *v = 1;
>
>}
>
>int main()
> {
> int words;
> int bytes;
> int overflow;
>
> //... whatever
> ovf(words, sizeof(int), &bytes, &overflow);
> if (overflow)
> printf("overflow");
>
>}
>
>It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> generated by GCC is as follows, call to ovf is eliminated, seems
>that
> GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
>to
> revise ovf to let it satisfy GCC? thanks in advance.


May be it helps to store the result of the multiplication i n a volatile
variable and use that variable in the division? Wouldn't that inhibit the
optimization?

 
Reply With Quote
 
sailer
Guest
Posts: n/a
 
      11-28-2011
On Nov 24, 4:38*pm, sailer <(E-Mail Removed)> wrote:
> On Nov 24, 2:46*pm, Tobias Mller <(E-Mail Removed)> wrote:
>
>
>
>
>
> > sailer <(E-Mail Removed)> wrote:
> > > Hi,

>
> > > I have the following code which was used tocheckwhether *the result
> > > *of (a * b) *is larger than the maximumintegervalue.

>
> > > ovf(int a, int b, int *r, int *v)
> > > *{
> > > * * * * **r = a * b;
> > > * * * * *if (b == 0 || a == *r / b)
> > > * * * * * * * * **v = 0;
> > > * * * * *else
> > > * * * * * * * * **v = 1;

>
> > > }

>
> > > int main()
> > > *{
> > > * * *int words;
> > > * * *int bytes;
> > > * * *intoverflow;

>
> > > * * //... whatever
> > > * * *ovf(words, sizeof(int), &bytes, &overflow);
> > > * * *if (overflow)
> > > * * * * printf("overflow");

>
> > > }

>
> > > It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> > > *generated by GCC is as follows, call to ovf is eliminated, seems
> > > that
> > > *GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> > > to
> > > *revise ovf to let it satisfy GCC? thanks in advance.

>
> > > main:
> > > * * * * *pushl * %ebp * *#
> > > * * * * *xorl * *%eax, %eax * * *#
> > > * * * * *movl * *%esp, %ebp * * *#,
> > > * * * * *popl * *%ebp * *#
> > > * * * * *ret
> > > * * * * *.size * main, .-main
> > > * * * * *.ident *"GCC: (GNU) 4.5.2"
> > > * * * * *.section * * * *.note.GNU-stack,"",@progbits

>
> > The possibility of such optimizations is one reasons, why intoverflowis
> > undefined behaviour.

>
> > The correctly formulated question (compiler neutral) would then be how to
> > implement this test without relying on UB. (some people on this list are a
> > bit picky about that)

>
> > You could take unsigned int instead, whereoverflowis defined:

>
> > ovf(int a, int b, unsigned int *r, int *v)
> > {
> > * * * * * *r = (unsigned int)a * b;
> > * * * * * if (b == 0 || (a == *r / b && r <= INT_MAX))
> > * * * * * * * * * *v = 0;
> > * * * * * else
> > * * * * * * * * * *v = 1;

>
> > }

>
> > This is just to illustrate, notice however that:
> > - this is really C rather than C++
> > - it does not work for underflows
> > - it probably leads to compiler warnings without some more casts
> > - I have not tested it.
> > - there are probably more efficient ways of achieving the same thing

>
> > Tobi

>
> Tobi,
>
> Really appreciate your replying, it helps much in understanding the
> background of the problem.
> I gave a try to use unsigned and INT_MAX but failed to address the
> issue, happened to find
> add "__attribute__ ((noinline))" before ovf solves it.


My mistake here, adding the attribute could force compiler to generate
call to 'ovf' but
the if-else code is still optimized out.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
check integer overflow with GCC 4.5.2 sailer C Programming 19 11-30-2011 05:01 PM
integer or long overflow... deancoo C++ 11 03-05-2005 11:13 PM
hhow to detect overflow in integer calculation John Black C++ 1 04-15-2004 05:28 AM
unsigned integer overflow behaviour bartek C++ 3 02-06-2004 09:47 PM
Integer overflow Enrico 'Trippo' Porreca C Programming 9 08-24-2003 10:24 AM



Advertisments