News for hackers. Stuff that matters.
Re:Myths about Integer Overflow in Rust by zAy0LfpBZLC8mAC on Friday April 29, 2016 @02:35PM (#11597783)
I think the only sensible thing to do is to have distinct operators for integer arithmetic (where the impossibility to represent a result obviously is an error that should be caught) and wraparound arithmetic that you can use if you actually need wraparound semantics (or where you need the speed and can prove that it does give you the correct result better than the compiler can).
Re:Myths about Integer Overflow in Rust by weinzierl on Friday April 29, 2016 @03:29PM (#11598162)
Swift has this and this is a sensible way to go but not the only one.

I personally would prefer integer overflow resulting in NaN like it does with IEEE floating point operations. Regher has written about this option a bit more in [1]. On the other hand, as long as we have no hardware support this is not going to fly.

If we consider current popular hardware as given, want to be as safe as possible while still retaining performance competitive with C/C++ the solution the Rust community chose is a very good one and one I can live with.

[1] http://blog.regehr.org/archives/641

Re:Myths about Integer Overflow in Rust by zAy0LfpBZLC8mAC on Friday April 29, 2016 @04:03PM (#11598369)
Well, I would kindof consider that to be an implementation of that approach, if you think of NaN as an error return. The important part is that you don't return a value that is arithmetically incorrect for the expected semantics, but not recognizable as such by itself.

I think the approach of Rust is stupid because it makes the fast but insecure option the default for all the code that's written without thinking about it too much that isn't in any way performance critical. Most arithmetic operators in code are not performance critical, only a few that are executed often, are, so it doesn't make much sense to make the behaviour that you need in that case the default, when that also is a security risk. And overflow checking only in debug builds is kindof useless from a security perspective.

Having different types instead of different operators also is weird. You don't have "additive integers" and "multiplicative integers" either, where the former's "+" operator does addition, while the latter's does multiplication (which is a form of (repeated) addition, after all!). If you have the same set of numbers to operate on, the obviously sensible thing to do is to have different operators for different ways to map pairs of those numbers to single numbers from the same set.

Re:Myths about Integer Overflow in Rust by weinzierl on Friday April 29, 2016 @07:00PM (#11599286)
It's not the same as an error return because the NaN propagates through all subsequent calculations.

In numerical code very often there are no checks for NaN at all. I'd even go so far to say that a lot of FORTRAN code in use today was written before NaN was introduced. I/O functions like printf or WRITE treat NaN properly so if something went wrong you end up with the string "NaN" in your output.

In rust the checked_... methods that return an Option come close to the NaN behaviour.

Re:Myths about Integer Overflow in Rust by zAy0LfpBZLC8mAC on Friday April 29, 2016 @07:52PM (#11599508)
NaN is a value that is returned to indicate that an operation could not be performed in the way that is normally expected. How is that not pretty much the definition of an error return?

Propagating an error return through subsequent computations is just monadic error handling ... which is, well, error handling?

Also, of course, there are NaN checks everywhere, as is evidenced by the error propagation. You can't propagate the sentinel value if you don't check for it. It just so happens that this check usually is implemented in hardware as part of every instruction for IEEE 754 numbers, so it's extremely fast in the error-free case and doesn't cause any code bloat, at the cost of some cycles being spent on otherwise useless error propagation in case an error occurs.

Now, what you are saying isn't exactly wrong--but I think it's much less confusing to think of it in this way.

Re:Myths about Integer Overflow in Rust by reycharles on Saturday April 30, 2016 @06:14AM (#11601142)
n+1 is a number.
Re:Myths about Integer Overflow in Rust by Alphasite_ on Friday April 29, 2016 @02:39PM (#11597810)
Sounds like what swift does, checked and unchecked arthritic operators.
Re:Myths about Integer Overflow in Rust by vog on Friday April 29, 2016 @02:52PM (#11597888)
Why do people invent these strange terms?

"wraparound arithmetic". "unchecked arithmetics". Really?

The correct term is modular arithmetic, which is well established in maths for centuries. And it is properly backed by a really nice and almost dead-simple theory (at least from a programmer's point of view). Is this no longer taught in school?

If you like to emphasize the fact that it's mostly modulo a power of two (2^n), then call it two's complement. However, that overemphasizes the binary representation, which I find most of the time more distracting than helpful.

As a side note, integer division is usually not performed in modular arithmetics, but addition, subtraction and multiplication are.

Re:Myths about Integer Overflow in Rust by jimktrains2 on Friday April 29, 2016 @03:47PM (#11598278)
It's modular arithmetic because of the internals of the processor, not because of some law-of-the-universe.

It could just as easy a processor not allow over- or under- flow operations. However, it's easiest to just truncate the number and essentially do modular arithmetic. That's the difference. Over- or under- flow, checked, wrap-around all refer to the state at which the operation's answer needs more space than it is given. Modular arithmetic and checked instructions are what to do in those situations.

Aside, division in modular arithmetic can be done, but it's not what most people want (hence why usually not performed). 4 / 3 mod 7 -> 4 * 5 mod 7 ( 5 is the multiplicative inverse of 3 mod 7 ( 3 * 5 = 1 mod 7) -> 6 mod 7

Re:Myths about Integer Overflow in Rust by vog on Saturday April 30, 2016 @03:45AM (#11600822)
> It's modular arithmetic because of the internals of the processor, not because of some law-of-the-universe

I beg to differ. There were various integer representations tried, such as having a separate "sign" bit on integers. But the two's complement finally was used by everyone. So there's something deeply unique to modulo arithmetics that none of the other representations could offer. This is not just about saving a few gates in the circuit.

> However, it's easiest to just truncate the number and essentially do modular arithmetic

The point is, there is no truncatenation step. It's just a side effect. If you build any naive adder circuit, substractor, multiplicator - even if you totally ignore negative numbers, you automatically have a full working two's complement, that works for negative numbers without any additional effort.

And why is that? Because the mathematical structure behind it is so dead-simple that it almost works by miracle. (except for division, which is highly non-intuitive and has more pitfalls than usual pitfall of division by zero.)

As a consequence of this simple math structure, it is very easy to build in hardware without any additional handling of nasty special cases.

Re:Myths about Integer Overflow in Rust by jimktrains2 on Saturday April 30, 2016 @11:07PM (#11604676)
> As a consequence of this simple math structure, it is very easy to build in hardware without any additional handling of nasty special cases.

Which is exactly my point! It's only the way we build things, not some hard-and-fast way things work intrinsically. I have no argument with it's an extremely simple way to deal with an over- or under- flow. But that's my point! It's a way to deal with the case, not the case itself!

Re:Myths about Integer Overflow in Rust by jimktrains2 on Sunday May 01, 2016 @09:06AM (#11606014)
I guess I missed my edit window:

> except for division, which is highly non-intuitive and has more pitfalls than usual pitfall of division by zero.

Division literally works the same way it does normally:

10 / 2 = 5 => 5 subtractions of 2 from 10 gives 0.

    0: 10
    1:  8
    2:  6
    3:  4
    4:  2
    5:  0
4 / 3 = 6 mod 7 => 6 subtractions of 3 from 4 gives 0

    0: 4
    1: 1
    2: 5
    3: 2
    4: 6
    5: 3
    6: 0
I wouldn't say it's fraught with pitfalls, just that it's not common to see. FWIW, in an under- or overflow- situation we normally don't want modular arithmetic, hence why we still attempt to trap instead of ignore it.
Re:Myths about Integer Overflow in Rust by vog on Monday May 02, 2016 @06:44AM (#11610413)
I was referring to the non-prime modulo values, such as 2^32 or 2^64. In those cases, you do not only have "well-defined" and "division by zero", but also "division with multiple valid results". More generally, this is the issue of zero divisors. [1]

Modulo 2^n, you have proper division only if you divide by odd numbers, then you have division by zero, and finally you have division by any other even number, which is very different from what people used to. There may be no solution, or two solutions, or many more solutions.

Yes, could can still solve them by reducing the modulo, but that's the extra pitfall that you don't have with plain integers or rationals.

[1] https://en.wikipedia.org/wiki/Zero_divisor

Re:Myths about Integer Overflow in Rust by khedoros on Friday April 29, 2016 @03:34PM (#11598193)
> Why do people invent these strange terms?

Same reason we talk about a "for loop" or a "while loop", instead of just a "conditional branch". Different words add different context to the concept that they're based on. For example, "modular arithmetic" doesn't include the context of checking for undesired leaks in Rust's arithmetic implementation. "Unchecked arithmetic" does.

Re:Myths about Integer Overflow in Rust by zAy0LfpBZLC8mAC on Friday April 29, 2016 @03:05PM (#11597993)
(2147483647 + 1) % m = -2147483648

What is the m?

Re:Myths about Integer Overflow in Rust by periodontal on Friday April 29, 2016 @05:52PM (#11599016)
2147483647 + 1 is congruent to -2147483648 modulo 4294967296.
Re:Myths about Integer Overflow in Rust by vardump on Friday April 29, 2016 @05:55PM (#11599025)
Maybe it's an Apple thing. Sometimes they make up silly names like "Grand Central Dispatch" for executing a block in parallel in multiple threads. "ARC" makes me still think "adaptive replacement cache", not "automatic reference counting". At least they don't call it "automatic retain count". After all, they used to call "reference count" as "retain count". Confused the heck out of me on my first exposure to Objective-C.

Not that others like Microsoft don't do the same thing, renaming commonly known concepts to something they made up. Like DEP vs NX vs XD. Or Interlocked* for atomic operations. Atomic add in Microsoftese is InterlockedAdd.

Re:Myths about Integer Overflow in Rust by renox on Friday April 29, 2016 @06:30PM (#11599172)
Unchecked != modulo in Rust case, I think that the compiler is free to generate either a trap on overflow or a modulo result. After all the MIPS has trap on overflow instructions..
Re:Myths about Integer Overflow in Rust by dllthomas on Saturday April 30, 2016 @04:00AM (#11600855)
> If you like to emphasize the fact that it's mostly modulo a power of two (2^n), then call it two's complement.

And it's signed, and negative numbers work by, well, two's complement...

Referring to unsigned integers, modulo a power of two, as "two's compliment" is at least weird.

Referring to integers with a different encoding of negative numbers as "two's complement" would be incorrect, even if they still wrap around near a power of two.