integer overflow behavior in other languages

S

Seebs

Ruby
Undefined, there is no available specs about that. Since ruby is
written in C, the behavior is probably the same as C.

Uh, no.

I'm pretty sure the answer is that overflow doesn't happen because you
silently switch to bignums if you need to. A quick check on irb confirms:
=> 36893488147419103230
=> Bignum

Hmm.
=> Bignum

Yeah, as expected, things up to one bit less than the native word size
(long story) are fixnums, past that it's bignums, there is no such thing
as overflow.

In this case, the lack of a definition is because the concept doesn't apply.

.... Not that this has much to do with C, but if you're going to be talking
about what lessons C should learn from other languages, it's important to do
slightly less cursory research.

IMHO, C's current handling of overflow is probably fine. Compilers do a
pretty good job of catching most of the significant error cases, I think.

-s
 
J

jacob navia

I have been researching this question to add it to the proposal for
integer overflow definition in C. Please add to the languages listed
below or correct me if I am wrong.


Java.
Wrap around. No special detection mechanism, as C now

C#
it has a "checked" construct that throws an exception on overflow:
using System;

class Overflow
{
static void Main()
{
try
{
int x = int.MaxValue + 1; // wraps to int.MinValue
int y = checked(int.MaxValue + 1); // throws
}
catch (OverflowException caught)
{
Console.WriteLine(caught);
}
}
}

FORTRAN
Compiler specific, apparently no language support.
This is the documentation from the HP forran (and C)
compilers:
http://docs.hp.com/en/B3906-90006/ch06s04.html
<quote>
To enable integer overflow checking for Fortran, use a !$HP$
CHECK_OVERFLOW INTEGER ON directive (in HP Fortran/9000, use
$CHECK_OVERFLOW INTEGER_4 or INTEGER_2) to obtain the overflow checking
code, and use an ON INTEGER OVERFLOW statement to handle the trap. (The
!$HP$ CHECK_OVERFLOW directive does not enable checking for operations
in libraries. Using the exponentiation operator involves a library call
in HP Fortran, so it is not possible to enable integer overflow checking
for exponentiation operations.)

There is no way to enable integer overflow checking in C. HP C provides
no mechanism to insert overflow checking code into your executable,
because the C language does not define integer overflow as an error.
<end quote>

Note that they say that integer overflow is not an error in C,
when in fact it is.

Python
Converts overflowing integers into longs and goes on. Of course this
is not so easy in compiled code.

Ada
Traps on integer overflow

Haskell
Uses IntS and IntegerS. Ints are like C ints, but IntegerS go smoothly
without overflowing.

Ruby
Undefined, there is no available specs about that. Since ruby is
written in C, the behavior is probably the same as C.
 
S

Seebs

If the implementation is in fact C, you're not curious as to how the
overflow is detected to make this silent widening possible?

Not particularly. I've read a bit of the internal code, and while I did
actually find a bug in an extension once, for the most part, the internals
don't strike me as particularly surprising or unusual.

.... Although I'd point out that Ruby is not particularly strictly-conforming
code, by any stretch of the imagination.

Looking at it:

Fixnums are smaller than machine words in Ruby. There's a long background,
but the key is, numbers being evaluated on a 64-bit system will be at most
63-bit values unless they are ALREADY bignums.

So, here's how multiply is done:

a = FIX2LONG(x);
if (a == 0) return x;

b = FIX2LONG(y);
c = a * b;
r = LONG2FIX(c);

if (FIX2LONG(r) != c || c/a != b) {
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
}
return r;

#define FIX2LONG(x) RSHIFT((long)x,1)
(LONG2FIX is just INT2FIX:)
#define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))

In short, the Ruby code assumes that if you multiply a pair of longs,
and there is overflow, you get a result which fails a sanity check.

Given that there's #ifdef VAX in here, I'm guessing this turns out to be true
in practice on a pretty broad range of systems.

-s
 
S

Seebs

True, in that interpreter. What I searched (and did not find)
is some kind of official document about the language so that
I could be sure that it is not a specific interpreter that does that
and maybe another not.

Ruby's young enough that matz's interpreter is functionally the standard.
I do not see how a compiler could check

a*b

at compile time in most cases... Yes, you can do constant propagation
but that has very tight limits on what can it do.

Maybe it wouldn't check it -- but in practice, I don't see many (if any)
bugs which have to do with overflow that the compiler failed to catch.

-s
 
B

bartc

Seebs said:
Uh, no.
Agree.


I'm pretty sure the answer is that overflow doesn't happen because you
silently switch to bignums if you need to. A quick check on irb confirms: ....
=> Bignum

Yeah, as expected, things up to one bit less than the native word size
(long story) are fixnums, past that it's bignums, there is no such thing
as overflow.

In this case, the lack of a definition is because the concept doesn't
apply.

... Not that this has much to do with C, but if you're going to be talking
about what lessons C should learn from other languages, it's important to
do
slightly less cursory research.

If the implementation is in fact C, you're not curious as to how the
overflow is detected to make this silent widening possible?
 
J

jacob navia

Seebs a écrit :
Uh, no.

I'm pretty sure the answer is that overflow doesn't happen because you
silently switch to bignums if you need to. A quick check on irb confirms:

=> 36893488147419103230

=> Bignum

Hmm.

=> Bignum

Yeah, as expected, things up to one bit less than the native word size
(long story) are fixnums, past that it's bignums, there is no such thing
as overflow.

True, in that interpreter. What I searched (and did not find)
is some kind of official document about the language so that
I could be sure that it is not a specific interpreter that does that
and maybe another not.

I downloaded irb and it seems to be like you said.
In this case, the lack of a definition is because the concept doesn't apply.

... Not that this has much to do with C, but if you're going to be talking
about what lessons C should learn from other languages, it's important to do
slightly less cursory research.

Yes. Sorry.
IMHO, C's current handling of overflow is probably fine. Compilers do a
pretty good job of catching most of the significant error cases, I think.

I do not see how a compiler could check

a*b

at compile time in most cases... Yes, you can do constant propagation
but that has very tight limits on what can it do.
 
K

Keith Thompson

jacob navia said:
I have been researching this question to add it to the proposal for
integer overflow definition in C. Please add to the languages listed
below or correct me if I am wrong.


Java.
Wrap around. No special detection mechanism, as C now

If I understand this correctly, it's quite different from C.
Signed integer overflow in C invokes undefined behavior; in Java, it
apparently yields a well-defined result. The bad this makes
a Java implementation that traps signed overflow non-conforming,
just as a C implementation that traps unsigned overflow would be.
The good with well-defined results, it should be possible to
detect signed overflow in Java after it's happened.

[...]
(quotation from HP manual follows):
There is no way to enable integer overflow checking in C. HP C
provides no mechanism to insert overflow checking code into your
executable, because the C language does not define integer overflow as
an error.
<end quote>

Note that they say that integer overflow is not an error in C,
when in fact it is.

Well, that depends on what you mean by "error". Signed overflow
in C is undefined behavior. This means, among other things, that
a conforming C implementation could catch it. It does sound like
the author of the HP manual misunderstood that point.

[...]
Ada
Traps on integer overflow

"Traps" meaning "raises an exception". Yes, but the check can be
suppressed, and at least one major compiler (GNAT, part of gcc)
suppresses the check unless you ask it not to. This means that GNAT
is non-conforming with default options. I've heard it said that
the gcc back-end, which GNAT uses, makes it difficult to generate
efficient overflow-checking code. I have no personal experience
to confirm or deny that.

[...]
Ruby
Undefined, there is no available specs about that. Since ruby is
written in C, the behavior is probably the same as C.

That's an unwarranted conclusion (and an incorrect one, as someone
else already mentioned).
 
B

bartc

Seebs said:
Not particularly. I've read a bit of the internal code, and while I did
actually find a bug in an extension once, for the most part, the internals
don't strike me as particularly surprising or unusual.

... Although I'd point out that Ruby is not particularly
strictly-conforming
code, by any stretch of the imagination.

Looking at it:

Fixnums are smaller than machine words in Ruby. There's a long
background,
but the key is, numbers being evaluated on a 64-bit system will be at most
63-bit values unless they are ALREADY bignums.

I'd noticed that (31-bits on my machine). So it makes the problem simpler by
not using the full integer range, making use of the top bit to help detect
overflow.

This is probably not an option for actual C applications. It does make you
wonder, if C overflow checking existed and was standardised, whether Ruby
could then have had Fixnums up to 32 or 64 bits, making some operations a
bit faster (not that you would notice in Ruby).
 
S

Seebs

This is probably not an option for actual C applications. It does make you
wonder, if C overflow checking existed and was standardised, whether Ruby
could then have had Fixnums up to 32 or 64 bits, making some operations a
bit faster (not that you would notice in Ruby).

No.

The reason fixnums don't use the whole range is so that you can have special
objects which are stored in a single machine word using a flag bit; the
overflow detection is a side-effect. (Also, the single bit doesn't solve the
problem for multiplication.)

-s
 
R

robertwessel2

I have been researching this question to add it to the proposal for
integer overflow definition in C. Please add to the languages listed
below or correct me if I am wrong.

Java.
Wrap around. No special detection mechanism, as C now

C#
it has a "checked" construct that throws an exception on overflow:
using System;

class Overflow
{
     static void Main()
     {
         try
         {
             int x = int.MaxValue + 1;          // wraps to int.MinValue
             int y = checked(int.MaxValue + 1); // throws
         }
         catch (OverflowException caught)
         {
             Console.WriteLine(caught);
         }
     }

}

FORTRAN
Compiler specific, apparently no language support.
This is the documentation from the HP forran (and C)
compilers:http://docs.hp.com/en/B3906-90006/ch06s04.html
<quote>
To enable integer overflow checking for Fortran, use a !$HP$
CHECK_OVERFLOW INTEGER ON directive (in HP Fortran/9000, use
$CHECK_OVERFLOW INTEGER_4 or INTEGER_2) to obtain the overflow checking
code, and use an ON INTEGER OVERFLOW statement to handle the trap. (The
!$HP$ CHECK_OVERFLOW directive does not enable checking for operations
in libraries. Using the exponentiation operator involves a library call
in HP Fortran, so it is not possible to enable integer overflow checking
for exponentiation operations.)

There is no way to enable integer overflow checking in C. HP C provides
no mechanism to insert overflow checking code into your executable,
because the C language does not define integer overflow as an error.
<end quote>

Note that they say that integer overflow is not an error in C,
when in fact it is.

Python
Converts overflowing integers into longs and goes on. Of course this
is not so easy in compiled code.

Ada
Traps on integer overflow

Haskell
Uses IntS and IntegerS. Ints are like C ints, but IntegerS go smoothly
without overflowing.

Ruby
Undefined, there is no available specs about that.  Since ruby is
written in C, the behavior is probably the same as C.



As I mentioned to you earlier, Cobol has an "on size error" construct
that will execute if the result of a calculation will not fit in the
destination (or several other conditions, like divide by zero). For
example:

compute x = a * 100 + b
on size error
display "It's too big, Jim!".
 
J

jacob navia

(e-mail address removed) a écrit :
As I mentioned to you earlier, Cobol has an "on size error" construct
that will execute if the result of a calculation will not fit in the
destination (or several other conditions, like divide by zero). For
example:

compute x = a * 100 + b
on size error
display "It's too big, Jim!".

Thanks a lot. I will add it to the list. This is similar to the C#
schema: Overflow check can be turned on for one expression.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top