check integer overflow with GCC 4.5.2

Discussion in 'C++' started by sailer, Nov 24, 2011.

  1. sailer

    sailer Guest

    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
    sailer, Nov 24, 2011
    #1
    1. Advertising

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


    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
    Tobias Müller, Nov 24, 2011
    #2
    1. Advertising

  3. sailer

    sailer Guest

    On Nov 24, 2:46 pm, Tobias Müller <> 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

    >
    > 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.
    sailer, Nov 24, 2011
    #3
  4. sailer

    Jorgen Grahn Guest

    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 .
    Jorgen Grahn, Nov 24, 2011
    #4
  5. sailer <> 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-every-c-programmer-should-know.html

    Tobi
    Tobias Müller, Nov 24, 2011
    #5
  6. "sailer" wrote in message
    news:...
    >
    >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?
    Fred Zwarts \(KVI\), Nov 25, 2011
    #6
  7. sailer

    sailer Guest

    On Nov 24, 4:38 pm, sailer <> wrote:
    > On Nov 24, 2:46 pm, Tobias Müller <> 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;
    > > >      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.
    sailer, Nov 28, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bartek
    Replies:
    3
    Views:
    3,084
    bartek
    Feb 6, 2004
  2. John Black
    Replies:
    1
    Views:
    4,494
    John Harrison
    Apr 15, 2004
  3. deancoo

    integer or long overflow...

    deancoo, Mar 5, 2005, in forum: C++
    Replies:
    11
    Views:
    752
    Pete Becker
    Mar 5, 2005
  4. Enrico 'Trippo' Porreca

    Integer overflow

    Enrico 'Trippo' Porreca, Aug 21, 2003, in forum: C Programming
    Replies:
    9
    Views:
    405
  5. sailer

    check integer overflow with GCC 4.5.2

    sailer, Nov 24, 2011, in forum: C Programming
    Replies:
    19
    Views:
    686
    Keith Thompson
    Nov 30, 2011
Loading...

Share This Page