Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #13834 > unrolled thread

check integer overflow with GCC 4.5.2

Started bysailer <xiangdong.ji@gmail.com>
First post2011-11-23 20:25 -0800
Last post2011-11-29 19:46 -0800
Articles 20 on this page of 25 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-23 20:25 -0800
    Re: check integer overflow with GCC 4.5.2 pete <pfiland@mindspring.com> - 2011-11-24 00:47 -0500
      Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-23 22:29 -0800
        Re: check integer overflow with GCC 4.5.2 "Philip Lantz" <prl@canterey.us> - 2011-11-24 01:23 -0800
          Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-27 23:14 -0800
            Re: check integer overflow with GCC 4.5.2 James Kuyper <jameskuyper@verizon.net> - 2011-11-28 07:04 -0500
            Re: check integer overflow with GCC 4.5.2 Noob <root@127.0.0.1> - 2011-11-29 14:12 +0100
              Re: check integer overflow with GCC 4.5.2 Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-29 16:16 +0200
              Re: check integer overflow with GCC 4.5.2 88888 Dihedral <dihedral88888@googlemail.com> - 2011-11-29 06:28 -0800
    Re: check integer overflow with GCC 4.5.2 Robert Wessel <robertwessel2@yahoo.com> - 2011-11-24 00:28 -0600
    Re: check integer overflow with GCC 4.5.2 Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-24 09:46 +0100
      Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-24 01:08 -0800
        Re: check integer overflow with GCC 4.5.2 "Philip Lantz" <prl@canterey.us> - 2011-11-24 01:26 -0800
          Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-27 23:09 -0800
      Re: check integer overflow with GCC 4.5.2 "io_x" <a@b.c.invalid> - 2011-11-24 14:19 +0100
    Re: check integer overflow with GCC 4.5.2 gwowen <gwowen@gmail.com> - 2011-11-24 09:10 -0800
    Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-27 23:21 -0800
      Re: check integer overflow with GCC 4.5.2 Keith Thompson <kst-u@mib.org> - 2011-11-28 16:31 -0800
        Re: check integer overflow with GCC 4.5.2 Ian Collins <ian-news@hotmail.com> - 2011-11-29 13:53 +1300
    Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-27 23:34 -0800
      Re: check integer overflow with GCC 4.5.2 pete <pfiland@mindspring.com> - 2011-11-28 18:59 -0500
        Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-29 19:44 -0800
          Re: check integer overflow with GCC 4.5.2 James Kuyper <jameskuyper@verizon.net> - 2011-11-30 11:08 -0500
            Re: check integer overflow with GCC 4.5.2 Keith Thompson <kst-u@mib.org> - 2011-11-30 09:01 -0800
    Re: check integer overflow with GCC 4.5.2 sailer <xiangdong.ji@gmail.com> - 2011-11-29 19:46 -0800

Page 1 of 2  [1] 2  Next page →


#13834 — check integer overflow with GCC 4.5.2

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-23 20:25 -0800
Subjectcheck integer overflow with GCC 4.5.2
Message-ID<649a64d1-3c3b-43d1-be20-a3b465118267@m10g2000vbc.googlegroups.com>
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

[toc] | [next] | [standalone]


#13837

Frompete <pfiland@mindspring.com>
Date2011-11-24 00:47 -0500
Message-ID<4ECDDA82.4C71@mindspring.com>
In reply to#13834
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.
> 
> 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

How about maybe:

#include <limits.h>

if (b == 0 || INT_MAX / b >= a)

-- 
pete

[toc] | [prev] | [next] | [standalone]


#13840

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-23 22:29 -0800
Message-ID<af78722e-ed85-4f3c-a721-8f4786f22cd6@m7g2000vbc.googlegroups.com>
In reply to#13837
On Nov 24, 1:47 pm, pete <pfil...@mindspring.com> wrote:
> 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.
>
> > 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
>
> How about maybe:
>
> #include <limits.h>
>
> if (b == 0 || INT_MAX / b >= a)
>
> --
> pete

Hi Pete,

Thanks for replying, I tried but no luck, call to ovf is still removed
by GCC.

[toc] | [prev] | [next] | [standalone]


#13846

From"Philip Lantz" <prl@canterey.us>
Date2011-11-24 01:23 -0800
Message-ID<op.v5f1pcaplahckh@cantereyd>
In reply to#13840
On Wed, 23 Nov 2011 22:29:10 -0800, sailer <xiangdong.ji@gmail.com> wrote:

> On Nov 24, 1:47 pm, pete <pfil...@mindspring.com> wrote:
>> 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.
>>
>> > 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
>>
>> How about maybe:
>>
>> #include <limits.h>
>>
>> if (b == 0 || INT_MAX / b >= a)
>
> Thanks for replying, I tried but no luck, call to ovf is still removed
> by GCC.

Perhaps this is because ovf still had undefined behavior in the case
where you would want overflow to be set. If you use Pete's suggestion
*before* doing the multiplication (and avoid performing the multiplication
when it indicates overflow), I suspect it will work.

Philip

[toc] | [prev] | [next] | [standalone]


#13995

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-27 23:14 -0800
Message-ID<3cb8bc00-3c7e-452d-a97c-dab639049df1@f36g2000prj.googlegroups.com>
In reply to#13846
On Nov 24, 5:23 pm, "Philip Lantz" <p...@canterey.us> wrote:
> On Wed, 23 Nov 2011 22:29:10 -0800, sailer <xiangdong...@gmail.com> wrote:
> > On Nov 24, 1:47 pm, pete <pfil...@mindspring.com> wrote:
> >> sailer 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;
> >> >     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
>
> >> How about maybe:
>
> >> #include <limits.h>
>
> >> if (b == 0 || INT_MAX / b >= a)
>
> > Thanks for replying, I tried but no luck, call to ovf is still removed
> > by GCC.
>
> Perhaps this is because ovf still had undefined behavior in the case
> where you would want overflow to be set. If you use Pete's suggestion
> *before* doing the multiplication (and avoid performing the multiplication
> when it indicates overflow), I suspect it will work.
>
> Philip

Here is the c code and asm code of main, call to 'ovf' is elimiated by
compiler :

#include <stdio.h>
#include <limits.h>

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

int main ()
{
        int words;
        int overflow;

        ovf(words, sizeof(int), &overflow);
        if (overflow)
                printf("overflow\n");

        return 0;
}

main:
        pushl   %ebp
        xorl    %eax, %eax
        movl    %esp, %ebp
        subl    $8, %esp
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.5.2"
        .section        .note.GNU-stack,"",@progbits


command line : gcc -O3 -m32 -msse2 a.c -S






[toc] | [prev] | [next] | [standalone]


#14006

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-11-28 07:04 -0500
Message-ID<javtbl$urh$1@dont-email.me>
In reply to#13995
On 11/28/2011 02:14 AM, sailer wrote:
...
> Here is the c code and asm code of main, call to 'ovf' is elimiated by
> compiler :
> 
> #include <stdio.h>
> #include <limits.h>
> 
> void
> ovf(int a, int b, int *v)
> {
>         if (b == 0 || (INT_MAX/b >= a))
>                 *v = 0;
>         else
>                 *v = 1;
> }
> 
> int main ()
> {
>         int words;
>         int overflow;
> 
>         ovf(words, sizeof(int), &overflow);

The behavior could be undefined, since 'words' is still uninitialized at
point, and could therefore, in principle, contain a trap representation,
though this is unlikely on most systems.

Even if it didn't have a trap representation, it would contain an
unspecified int value, and could therefore cause ovf() to put either 0
or 1 in overflow. gcc would therefore be within it's rights to assume
that you don't care whether it is a 0 or a 1, and to write code that
assumes whichever value is more convenient for the compiler, which would
be 0, because it allows optimizing away the call to printf(). I don't
know if that's what gcc actually did, but it would be perfectly legal if
it did.

>         if (overflow)
>                 printf("overflow\n");
> 
>         return 0;
> }
> 
> main:
>         pushl   %ebp
>         xorl    %eax, %eax
>         movl    %esp, %ebp
>         subl    $8, %esp
>         leave
>         ret
>         .size   main, .-main
>         .ident  "GCC: (GNU) 4.5.2"
>         .section        .note.GNU-stack,"",@progbits
> 
> 
> command line : gcc -O3 -m32 -msse2 a.c -S

Even when I change your code to initialize 'words', the result was still
comparably short. There's a simple reason for this: ovf() is called only
once, with only a single fixed set of input arguments. gcc apparently
inlined the code of that function, and determined what it's result would
be with those inputs. It therefore optimized away the code that computed
the result, and replaced it with code that acted as though the result
had already been obtained.

Giving ovf() arguments that depend upon input data from the command
line, or from an input stream, or from a call to rand() would prevent
pre-computation of the results of ovf() like this.

Putting ovf() in a different translation unit would prevent the
in-lining of ovf().
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#14036

FromNoob <root@127.0.0.1>
Date2011-11-29 14:12 +0100
Message-ID<jb2lnp$40u$1@dont-email.me>
In reply to#13995
sailer wrote:

> Here is the c code and asm code of main, call to 'ovf' is
> eliminated by compiler :
> 
> #include <stdio.h>
> #include <limits.h>
> 
> void
> ovf(int a, int b, int *v)
> {
>         if (b == 0 || (INT_MAX/b >= a))
>                 *v = 0;
>         else
>                 *v = 1;
> }
> 
> int main ()
> {
>         int words;
>         int overflow;
> 
>         ovf(words, sizeof(int), &overflow);
>         if (overflow)
>                 printf("overflow\n");
> 
>         return 0;
> }
> 
> main:
>         pushl   %ebp
>         xorl    %eax, %eax
>         movl    %esp, %ebp
>         subl    $8, %esp
>         leave
>         ret
>         .size   main, .-main
>         .ident  "GCC: (GNU) 4.5.2"
>         .section        .note.GNU-stack,"",@progbits
> 
> 
> command line : gcc -O3 -m32 -msse2 a.c -S

$ cat ovf.c
#include <limits.h>
int mul_overflow(int a, int b)
{
  return b && a > INT_MAX/b;
}

$ gcc -S -O3 -Wall -Wextra ovf.c
$ cat ovf.s
        .file   "ovf.c"
        .text
        .p2align 4,,15
.globl _mul_overflow
        .def    _mul_overflow;  .scl    2;      .type   32;     .endef
_mul_overflow:
        pushl   %ebp
        xorl    %eax, %eax
        movl    %esp, %ebp
        movl    12(%ebp), %ecx
        testl   %ecx, %ecx
        je      L2
        movl    $2147483647, %eax
        movl    %eax, %edx
        sarl    $31, %edx
        idivl   %ecx
        cmpl    8(%ebp), %eax
        setl    %al
        movzbl  %al, %eax
L2:
        popl    %ebp
        ret

[toc] | [prev] | [next] | [standalone]


#14039

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-11-29 16:16 +0200
Message-ID<87wraj3tg9.fsf@bazspaz.fatphil.org>
In reply to#14036
Noob <root@127.0.0.1> writes:
> $ cat ovf.c
> #include <limits.h>
> int mul_overflow(int a, int b)
> {
>   return b && a > INT_MAX/b;
> }

so -99999 * 99999 won't overflow?

Phil
-- 
Unix is simple. It just takes a genius to understand its simplicity
-- Dennis Ritchie (1941-2011), Unix Co-Creator

[toc] | [prev] | [next] | [standalone]


#14040

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-11-29 06:28 -0800
Message-ID<5845511.396.1322576921182.JavaMail.geo-discussion-forums@prgi20>
In reply to#14036
On Tuesday, November 29, 2011 9:12:29 PM UTC+8, Noob wrote:
> sailer wrote:
> 
> > Here is the c code and asm code of main, call to 'ovf' is
> > eliminated by compiler :
> > 
> > #include <stdio.h>
> > #include <limits.h>
> > 
> > void
> > ovf(int a, int b, int *v)
> > {
> >         if (b == 0 || (INT_MAX/b >= a))
> >                 *v = 0;
> >         else
> >                 *v = 1;
> > }
> > 
> > int main ()
> > {
> >         int words;
> >         int overflow;
> > 
> >         ovf(words, sizeof(int), &overflow);
> >         if (overflow)
> >                 printf("overflow\n");
> > 
> >         return 0;
> > }
> > 
> > main:
> >         pushl   %ebp
> >         xorl    %eax, %eax
> >         movl    %esp, %ebp
> >         subl    $8, %esp
> >         leave
> >         ret
> >         .size   main, .-main
> >         .ident  "GCC: (GNU) 4.5.2"
> >         .section        .note.GNU-stack,"",@progbits
> > 
> > 
> > command line : gcc -O3 -m32 -msse2 a.c -S
> 
> $ cat ovf.c
> #include <limits.h>
> int mul_overflow(int a, int b)
> {
>   return b && a > INT_MAX/b;
> }
> 
> $ gcc -S -O3 -Wall -Wextra ovf.c
> $ cat ovf.s
>         .file   "ovf.c"
>         .text
>         .p2align 4,,15
> .globl _mul_overflow
>         .def    _mul_overflow;  .scl    2;      .type   32;     .endef
> _mul_overflow:
>         pushl   %ebp
>         xorl    %eax, %eax
>         movl    %esp, %ebp
>         movl    12(%ebp), %ecx
>         testl   %ecx, %ecx
>         je      L2
>         movl    $2147483647, %eax
>         movl    %eax, %edx
>         sarl    $31, %edx
>         idivl   %ecx
>         cmpl    8(%ebp), %eax
>         setl    %al
>         movzbl  %al, %eax
> L2:
>         popl    %ebp
>         ret

If I know the push down types of all arguments in a function in  C in a platform, it is trivial to pick all those well packed arguments in the stack in a rcver after a long or a short jump. That assumes that callers pushes everything right down the stack or the heap. 

[toc] | [prev] | [next] | [standalone]


#13839

FromRobert Wessel <robertwessel2@yahoo.com>
Date2011-11-24 00:28 -0600
Message-ID<vvorc7l81vf72qemplnbbu20dn7f0tmkf5@4ax.com>
In reply to#13834
On Wed, 23 Nov 2011 20:25:50 -0800 (PST), sailer
<xiangdong.ji@gmail.com> 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 result of signed integer overflow is undefined, thus an
implementation can do anything it wants in such a case.  So there's no
issue with GCC per se.  And note that if "a*b" overflows, all bets are
off, your program could do anything at all at that point, and the
subsequent code is approximately meaningless.

Now *unsigned* arithmetic does not overflow in that sense, as it's
defined to happen modulo 2**n.  So if you can convert that to use
unsigned arithmetic, there's an easy solution.

If you must support signed operands, it's going to be messier.  You
could take the absolute value of both operands, determine the sign of
the result, and then multiply them *unsigned*, and then check that for
overflow by doing the divide test (as in your code, except unsigned)
*and* checking if the result is greater than INT_MAX or -INT_MIN,
depending on what the sign of the result should be.

Simplest would be if your compiler supports a big enough type to store
(-INT_MIN)**2.  If you at least have a long long (or similar) type
that's twice the size of an int, you can just do the multiplication in
the long long type, and check that for overflow (less than INT_MIN or
greater than INT_MAX).  Although that sort of approach is not portable
(even if all your compilers have long long, there's no guarantee that
it's twice the size of an int).

Doing a limited two-word multiprecision multiplication routine would
work too, but is likely to be slower than any of the above.

[toc] | [prev] | [next] | [standalone]


#13843

FromVincenzo Mercuri <vincenzo.mercuri@yahoo.it>
Date2011-11-24 09:46 +0100
Message-ID<gLOdnQCRNMn6mVPTnZ2dnUVZ8nudnZ2d@giganews.com>
In reply to#13834
sailer ha scritto:
> 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;
> }
[...]

Since you are concerned with "signed int"s you should check against
both INT_MAX and INT_MIN. I just wrote the following function "overflow()"
(sorry for the poor choice of its name), that should do the trick
(it takes the two factors and returns 1 if an overflow will occur, 0 if 
not):

#include <stdio.h>
#include <limits.h>

int overflow(int a, int b)
{
   if( b > 0 ) {
     if( (a > 0 && b <= INT_MAX / a) ||
         (a <= 0 && a >= INT_MIN / b) )
       return 0;
     else return 1;
   } else { /* b <= 0 */
     if( (a > 0 && b >= INT_MIN / a) ||
         (a <= 0 && (b == 0 || a >= INT_MAX / b)) )
       return 0;
     else return 1;
   }
}

void result(int a, int b)
{
   printf("\na = %d, b = %d\n", a, b), overflow(a, b) ?
   printf("[overflow detected]\n") :
   printf("[result = %d]\n", a * b);
}

int main(void)
{
   printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
   result(INT_MAX, INT_MAX);
   result(INT_MIN, INT_MIN);
   result(INT_MIN, INT_MAX);
   result(4000000, -80000);
   result(20000, 20000);
   result(0, 4);
   result(3, 0);
   result(0, 0);
   return 0;
}

-- 
Vincenzo Mercuri | www.backbox.org

[toc] | [prev] | [next] | [standalone]


#13845

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-24 01:08 -0800
Message-ID<15275059-737c-40b0-b9b8-d875104d7f1f@m7g2000vbc.googlegroups.com>
In reply to#13843
On Nov 24, 4:46 pm, Vincenzo Mercuri <vincenzo.merc...@yahoo.it>
wrote:
> sailer ha scritto:> 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;
> > }
>
> [...]
>
> Since you are concerned with "signed int"s you should check against
> both INT_MAX and INT_MIN. I just wrote the following function "overflow()"
> (sorry for the poor choice of its name), that should do the trick
> (it takes the two factors and returns 1 if an overflow will occur, 0 if
> not):
>
> #include <stdio.h>
> #include <limits.h>
>
> int overflow(int a, int b)
> {
>    if( b > 0 ) {
>      if( (a > 0 && b <= INT_MAX / a) ||
>          (a <= 0 && a >= INT_MIN / b) )
>        return 0;
>      else return 1;
>    } else { /* b <= 0 */
>      if( (a > 0 && b >= INT_MIN / a) ||
>          (a <= 0 && (b == 0 || a >= INT_MAX / b)) )
>        return 0;
>      else return 1;
>    }
>
> }
>
> void result(int a, int b)
> {
>    printf("\na = %d, b = %d\n", a, b), overflow(a, b) ?
>    printf("[overflow detected]\n") :
>    printf("[result = %d]\n", a * b);
>
> }
>
> int main(void)
> {
>    printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
>    result(INT_MAX, INT_MAX);
>    result(INT_MIN, INT_MIN);
>    result(INT_MIN, INT_MAX);
>    result(4000000, -80000);
>    result(20000, 20000);
>    result(0, 4);
>    result(3, 0);
>    result(0, 0);
>    return 0;
>
> }
>
> --
> Vincenzo Mercuri |www.backbox.org

Thanks all for your help, currently I'm using "__attribute__
((noinline))" to bypass the issue.

[toc] | [prev] | [next] | [standalone]


#13847

From"Philip Lantz" <prl@canterey.us>
Date2011-11-24 01:26 -0800
Message-ID<op.v5f1uhu7lahckh@cantereyd>
In reply to#13845
On Thu, 24 Nov 2011 01:08:28, sailer wrote:

> On Nov 24, 4:46 pm, Vincenzo Mercuri wrote:
>> sailer ha scritto:> 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;
>> > }
>>
>> [...]
>>
>> Since you are concerned with "signed int"s you should check against
>> both INT_MAX and INT_MIN. I just wrote the following function  
>> "overflow()"
>> (sorry for the poor choice of its name), that should do the trick
>> (it takes the two factors and returns 1 if an overflow will occur, 0 if
>> not):
>>
>> #include <stdio.h>
>> #include <limits.h>
>>
>> int overflow(int a, int b)
>> {
>>    if( b > 0 ) {
>>      if( (a > 0 && b <= INT_MAX / a) ||
>>          (a <= 0 && a >= INT_MIN / b) )
>>        return 0;
>>      else return 1;
>>    } else { /* b <= 0 */
>>      if( (a > 0 && b >= INT_MIN / a) ||
>>          (a <= 0 && (b == 0 || a >= INT_MAX / b)) )
>>        return 0;
>>      else return 1;
>>    }
>>
>> }
>>
>> void result(int a, int b)
>> {
>>    printf("\na = %d, b = %d\n", a, b), overflow(a, b) ?
>>    printf("[overflow detected]\n") :
>>    printf("[result = %d]\n", a * b);
>>
>> }
>>
>> int main(void)
>> {
>>    printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
>>    result(INT_MAX, INT_MAX);
>>    result(INT_MIN, INT_MIN);
>>    result(INT_MIN, INT_MAX);
>>    result(4000000, -80000);
>>    result(20000, 20000);
>>    result(0, 4);
>>    result(3, 0);
>>    result(0, 0);
>>    return 0;
>>
>> }
>
> Thanks all for your help, currently I'm using "__attribute__
> ((noinline))" to bypass the issue.

I doubt that this avoids the undefined behavior in ovf, so you still
may find that it does not work reliably.

Philip

[toc] | [prev] | [next] | [standalone]


#13993

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-27 23:09 -0800
Message-ID<74d429b4-4ebb-47f3-88fb-a0d136075ad2@n22g2000prh.googlegroups.com>
In reply to#13847
On Nov 24, 5:26 pm, "Philip Lantz" <p...@canterey.us> wrote:
> On Thu, 24 Nov 2011 01:08:28, sailer wrote:
> > On Nov 24, 4:46 pm, Vincenzo Mercuri wrote:
> >> sailer ha scritto:> 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;
> >> > }
>
> >> [...]
>
> >> Since you are concerned with "signed int"s you shouldcheckagainst
> >> both INT_MAX and INT_MIN. I just wrote the following function
> >> "overflow()"
> >> (sorry for the poor choice of its name), that should do the trick
> >> (it takes the two factors and returns 1 if an overflow will occur, 0 if
> >> not):
>
> >> #include <stdio.h>
> >> #include <limits.h>
>
> >> int overflow(int a, int b)
> >> {
> >>    if( b > 0 ) {
> >>      if( (a > 0 && b <= INT_MAX / a) ||
> >>          (a <= 0 && a >= INT_MIN / b) )
> >>        return 0;
> >>      else return 1;
> >>    } else { /* b <= 0 */
> >>      if( (a > 0 && b >= INT_MIN / a) ||
> >>          (a <= 0 && (b == 0 || a >= INT_MAX / b)) )
> >>        return 0;
> >>      else return 1;
> >>    }
>
> >> }
>
> >> void result(int a, int b)
> >> {
> >>    printf("\na = %d, b = %d\n", a, b), overflow(a, b) ?
> >>    printf("[overflow detected]\n") :
> >>    printf("[result = %d]\n", a * b);
>
> >> }
>
> >> int main(void)
> >> {
> >>    printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
> >>    result(INT_MAX, INT_MAX);
> >>    result(INT_MIN, INT_MIN);
> >>    result(INT_MIN, INT_MAX);
> >>    result(4000000, -80000);
> >>    result(20000, 20000);
> >>    result(0, 4);
> >>    result(3, 0);
> >>    result(0, 0);
> >>    return 0;
>
> >> }
>
> > Thanks all for your help, currently I'm using "__attribute__
> > ((noinline))" to bypass the issue.
>
> I doubt that this avoids the undefined behavior in ovf, so you still
> may find that it does not work reliably.
>
> Philip

Yes, you are right, just found the ovf is still treated by compiler as
undefined.

[toc] | [prev] | [next] | [standalone]


#13854

From"io_x" <a@b.c.invalid>
Date2011-11-24 14:19 +0100
Message-ID<4ece43c2$0$1389$4fafbaef@reader1.news.tin.it>
In reply to#13843
"Vincenzo Mercuri" <vincenzo.mercuri@yahoo.it> ha scritto nel messaggio 
news:gLOdnQCRNMn6mVPTnZ2dnUVZ8nudnZ2d@giganews.com...
> sailer ha scritto:
>> 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;
>> }
> [...]
>
> Since you are concerned with "signed int"s you should check against
> both INT_MAX and INT_MIN. I just wrote the following function "overflow()"
> (sorry for the poor choice of its name), that should do the trick
> (it takes the two factors and returns 1 if an overflow will occur, 0 if not):
>
> #include <stdio.h>
> #include <limits.h>
>
> int overflow(int a, int b)
> {
>   if( b > 0 ) {
>     if( (a > 0 && b <= INT_MAX / a) ||
>         (a <= 0 && a >= INT_MIN / b) )
>       return 0;
>     else return 1;
>   } else { /* b <= 0 */
>     if( (a > 0 && b >= INT_MIN / a) ||
>         (a <= 0 && (b == 0 || a >= INT_MAX / b)) )
>       return 0;
>     else return 1;
>   }
> }

caro vincenzino
il troll ha da dirti qualche cosa:
percio' per calcolare il solo verflow di a*b tu fai
da 1 a 3 divisioni....

> void result(int a, int b)
> {
>   printf("\na = %d, b = %d\n", a, b), overflow(a, b) ?
>   printf("[overflow detected]\n") :
>   printf("[result = %d]\n", a * b);
> }
>
> int main(void)
> {
>   printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
>   result(INT_MAX, INT_MAX);
>   result(INT_MIN, INT_MIN);
>   result(INT_MIN, INT_MAX);
>   result(4000000, -80000);
>   result(20000, 20000);
>   result(0, 4);
>   result(3, 0);
>   result(0, 0);
>   return 0;
> }
>
> -- 
> Vincenzo Mercuri | www.backbox.org 

[toc] | [prev] | [next] | [standalone]


#13864

Fromgwowen <gwowen@gmail.com>
Date2011-11-24 09:10 -0800
Message-ID<bb0e0f52-d3b7-4e34-9c1c-46724ce65187@da3g2000vbb.googlegroups.com>
In reply to#13834
On Nov 24, 4:25 am, sailer <xiangdong...@gmail.com> wrote:

> 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.

Not quite the question you asked, but ...

-O2 (and higher) turn on `-fstrict-overflow', and, to quote from the
fine manual: "For C (and C++) this means that overflow when doing
arithmetic with signed numbers is undefined, which means that the
compiler may assume that it will not happen.  This permits various
optimizations..."

So try, -O2 -fno-strict-overflow to disable this optimization.

[toc] | [prev] | [next] | [standalone]


#13996

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-27 23:21 -0800
Message-ID<e15fe1ed-9374-4b6f-8dc5-26bcc0e611d8@20g2000prn.googlegroups.com>
In reply to#13834
On Nov 24, 12:25 pm, sailer <xiangdong...@gmail.com> 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

I rewrite the c code to the follows and checking overflow works with
GCC 4.5.2 when enabling -O3,
is it safe enough? thanks.


#include <stdio.h>
#include <limits.h>

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

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

        ovf(words, sizeof(int), &bytes, &overflow);
        if (overflow)
                printf("overflow\n");

        return 0;
}


[toc] | [prev] | [next] | [standalone]


#14018

FromKeith Thompson <kst-u@mib.org>
Date2011-11-28 16:31 -0800
Message-ID<ln62i3srai.fsf@nuthaus.mib.org>
In reply to#13996
sailer <xiangdong.ji@gmail.com> writes:
[...]
> I rewrite the c code to the follows and checking overflow works with
> GCC 4.5.2 when enabling -O3,
> is it safe enough? thanks.

No.

> #include <stdio.h>
> #include <limits.h>
>
> void
> ovf(int a, int b, int *v, unsigned int *r)
> {
>         *r = a * b;

If the mathematical result of multiplying a and b is outside
the range INT_MIN .. INT_MAX, then the behavior of the above is
undefined.  Nothing you do *after* performing the multiplication can
change that.  For example, a conforming implementation could cause
your program to terminate as soon as the multiplication is attempted.

>         if (b == 0 || (a = *r/b && *r <= INT_MAX))
>                 *v = 0;
>         else
>                 *v = 1;
> }
>
> int main ()
> {
>         int words;
>         int bytes;
>         int overflow;
>
>         ovf(words, sizeof(int), &bytes, &overflow);

And you're passing an uninitialized value to ovf().

And I *think* you've got the 3rd and 4th arguments reversed.
It's hard to tell because you called the parameters "v" and "r"
rather than something legible.

>         if (overflow)
>                 printf("overflow\n");
>
>         return 0;
> }

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#14019

FromIan Collins <ian-news@hotmail.com>
Date2011-11-29 13:53 +1300
Message-ID<9jiooiF4d0U27@mid.individual.net>
In reply to#14018
On 11/29/11 01:31 PM, Keith Thompson wrote:
> sailer<xiangdong.ji@gmail.com>  writes:
>>
>> int main ()
>> {
>>          int words;
>>          int bytes;
>>          int overflow;
>>
>>          ovf(words, sizeof(int),&bytes,&overflow);
>
> And you're passing an uninitialized value to ovf().
>
> And I *think* you've got the 3rd and 4th arguments reversed.
> It's hard to tell because you called the parameters "v" and "r"
> rather than something legible.

Add to that he is passing the wrong type (pointer to int rather than 
pointer to unsigned) which will cause gcc to whinge.


-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#13998

Fromsailer <xiangdong.ji@gmail.com>
Date2011-11-27 23:34 -0800
Message-ID<679f35bf-6b41-49c5-b873-168c4c6e8c82@f3g2000pri.googlegroups.com>
In reply to#13834
On Nov 24, 12:25 pm, sailer <xiangdong...@gmail.com> 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;
>     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


I rewrite the c code to the follows and checking overflow works with
 GCC 4.5.2 when enabling -O3,
 is it safe enough? thanks.

#include <stdio.h>
 #include <limits.h>

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

}

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

        ovf(words, sizeof(int), &bytes, &overflow);
         if (overflow)
                 printf("overflow\n");

        return 0;
}

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web