[rust-dev] Integer overflow, round -2147483648

Gábor Lehel glaebhoerl at gmail.com
Sun Jun 22 16:26:56 PDT 2014


On Sun, Jun 22, 2014 at 11:05 PM, Daniel Micay <danielmicay at gmail.com>
wrote:

> On 22/06/14 09:31 AM, Gábor Lehel wrote:
> >
> > The prospect of future architectures with cheaper (free) overflow
> > checking isn't my primary motivation, though if we also end up better
> > prepared for them as a side effect, that's icing on the cake.
>
> It's never going to be free or even cheap. Replacing very common pure
> operations with impure ones in most code will destroy performance. Rust
> relies heavily on compiler optimizations to even come close to C level
> performance. Anyway, no one has offered an explanation of how they're
> planning on integrating this into LLVM and how they propose turning a
> trapping operation into unwinding across various platforms.
>

> > My primary motivation is that, outside of a couple of specialized cases
> > like hashing and checksums, wraparound semantics on overflow is
> > **wrong**. It may be well-defined behavior, and it may be fast, but it's
> > **wrong**. What's the value of a well-defined, performant semantics
> > which does the wrong thing?
>
> Few functions check all of the necessary preconditions. For example, a
> binary search implementation doesn't check to see if the array is
> sorted.  It's not incorrect to require a precondition from the caller
> and overflow is only one of countless cases of this.
>

Checking preconditions is a good thing. The fact that we can't have the
good thing in some instances is not an argument for not having it in other
instances.


>
> Choosing to enforce invariants in the type system or checking them at
> runtime is always a compromise, and Rust eschews runtime checks not
> strictly required for memory safety.
>
> In some cases, the type system has been leveraged to enforce invariants
> at compile-time (Ord vs. PartialOrd) but even though that's quite easy
> to sidestep, it's not without drawbacks.
>
> > I also agree that performance is non-negotiable in this case, however.
> > The only good thing about always wrong is that it's not that hard to do
> > better.
> >
> > Given the circumstances, I think the least bad outcome we could achieve,
> > and which we *should* aim to achieve, would be this:
> >
> >  * Where performance is known to not be a requirement, Rust code in the
> > wild uses either overflow-checked arithmetic or unbounded integer types,
> > with the choice between them depending on ergonomic and semantic
> > considerations.
> >
> >  * When the performance requirement can't be ruled out, Rust code in the
> > wild uses arithmetic for which overflow checking can be turned on or off
> > with a compiler flag. For testing and debugging, it is turned on. For
> > production and benchmarks, it is turned off.
>
> The Rust developers have been consistently opposed to introducing
> dialects of the language via compiler switches.


We already have `debug_assert`. I'm essentially proposing to turn overflow
checks into `debug_assert`s. `debug_assert`s are something we already have,
and not a new dialect.


> I brought up the issue
> of macros and syntax extensions but you've chosen to ignore that.
>

The assumption of bad faith is appreciated. I must have missed it
accidentally. If there's an issue, I'd be interested to know about it.

Could you point out where you brought it up? A Ctrl-F over the thread finds
the above comment as the only occurrence of the words "macro" and
"extension".



>
> >  * For code where wraparound semantics is desired, the appropriate
> > facilities are also available.
> >
> > Given the discussion so far, the design I'd be leaning toward to
> > accomplish the above might be something like this:
> >
> >  * Two sets of fixed-sized integer types are available in the `prelude`.
> >
> >  * `u8`..`u64`, `i8`..`i64`, `int`, and `uint` have unspecified results
> > on overflow (**not** undefined behavior). A compiler flag turns overflow
> > checks on or off. Essentially, the checks are `debug_assert`s, though
> > whether they should be controlled by the same flag is open to debate.
> >
> >  * `uc8`..`uc64`, `ic8`..`ic64`, `intc`, and `uintc` are *always*
> > checked for overflow, regardless of flags. (Names are of course open to
> > bikeshedding.)
> >
> >  * Given that these are not really different semantically, automatic
> > coercions between corresponding types can be considered. (Even then, for
> > `a + b` where `a: int` and `b: intc`, explicit disambiguation would
> > presumably still be required.)
> >
> >  * Unbounded integer types using owned memory allocation are available
> > in the `prelude`. I might prefer to call them `Integer` and `Natural`
> > instead of `BigInt` and `BigUint`.
> >
> >  * Types and/or operations which wrap around on overflow are available
> > in the standard library. Given how specialized the use cases for these
> > seem to be, perhaps they could even go directly in the `hash` module.
> > It's not clear to me yet whether a separate set of types (`uw8`..`uw64`,
> > `iw8`..`iw64`) or just a separate set of operations on the `prelude`
> > types (e.g. `trait WrappingAdd`) would be preferable.
>
> A `Vec<u32>` and `Vec<uw32>` would be entirely distinct types. That
> alone is going to cause performance issues and will make the language
> more painful to use.


That's a good point, and an argument in favor of different operators rather
than different types.

(It's also something that would be solved by the `Coercible` trait.)


> It's already pushing the boundaries of what people
> will be willing to accept with features like strictly checked move
> semantics and reference lifetimes.
>
> >  * Unbounded integer types which use garbage collected allocation are
> > available in the `gc` module.
>
> It doesn't sense to have 3 separate implementations of big integers for
> reference counting, atomic reference counting and task-local tracing
> garbage collection.
>

Coincidentally, I didn't propose it. I proposed one implementation with
owned allocation (which we already have) in the `prelude` and one with
tracing GC allocation in the `gc` module.



>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140623/6897f980/attachment.html>


More information about the Rust-dev mailing list