Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #13834 > unrolled thread
| Started by | sailer <xiangdong.ji@gmail.com> |
|---|---|
| First post | 2011-11-23 20:25 -0800 |
| Last post | 2011-11-29 19:46 -0800 |
| Articles | 20 on this page of 25 — 13 participants |
Back to article view | Back to comp.lang.c
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 →
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-11-23 20:25 -0800 |
| Subject | check 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]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "Philip Lantz" <prl@canterey.us> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Noob <root@127.0.0.1> |
|---|---|
| Date | 2011-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]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-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]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2011-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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2011-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]
| From | Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "Philip Lantz" <prl@canterey.us> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "io_x" <a@b.c.invalid> |
|---|---|
| Date | 2011-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]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | sailer <xiangdong.ji@gmail.com> |
|---|---|
| Date | 2011-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