-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clarify extreme operator behaviour #1237
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,10 +125,14 @@ The error conditions that can arise, and their defined results, are as | |
follows. The intention is that the defined results are the same as the | ||
defined results today. The only change is that now a panic may result. | ||
|
||
- The operations `+`, `-`, `*`, `/`, `%` can underflow and | ||
overflow. | ||
- The operations `+`, `-`, `*`, can underflow and overflow. When checking is | ||
enabled this will panic. When checking is disabled this will two's complement | ||
wrap. | ||
- The operations `/`, `%` are nonsensical for the arguments `INT_MIN` and `-1`. | ||
When this occurs there is an unconditional panic. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe division and remainder by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rust-lang/rust#24500 and rust-lang/rust#23154 and rust-lang/rust#22020 all seem to involve unary negation checking for overflow, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to work for me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, I used [17:13] <eddyb> playbot: let x = std::i32::MIN; -x
[17:13] [Notice] -playbot to #rust-internals- -2147483648 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding |
||
- Shift operations (`<<`, `>>`) can shift a value of width `N` by more | ||
than `N` bits. | ||
than `N` bits. This is prevented by unconditionally masking the bits | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is "this", that is prevented here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The undefined behavior that results from an overlong shift, presumably. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's what I assume it means, but there's no description of that undefined behavior which "this" could refer to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strictly speaking at this level Undefined Behaviour in LLVM in not an object -- this is Rust's semantics. Will clarify. |
||
of the right-hand-side to wrap modulo `N`. | ||
|
||
## Enabling overflow checking | ||
|
||
|
@@ -145,7 +149,7 @@ potential overflow (and, in particular, for code where overflow is | |
expected and normal, they will be immediately guided to use the | ||
wrapping methods introduced below). However, because these checks will | ||
be compiled out whenever an optimized build is produced, final code | ||
wilil not pay a performance penalty. | ||
will not pay a performance penalty. | ||
|
||
In the future, we may add additional means to control when overflow is | ||
checked, such as scoped attributes or a global, independent | ||
|
@@ -451,17 +455,7 @@ were: | |
|
||
# Unresolved questions | ||
|
||
The C semantics of wrapping operations in some cases are undefined: | ||
|
||
- `INT_MIN / -1`, `INT_MIN % -1` | ||
- Shifts by an excessive number of bits | ||
|
||
This RFC takes no position on the correct semantics of these | ||
operations, simply preserving the existing semantics. However, it may | ||
be worth trying to define the wrapping semantics of these operations | ||
in a portable way, even if that implies some runtime cost. Since these | ||
are all error conditions, this is an orthogonal topic to the matter of | ||
overflow. | ||
None today (see Updates section below). | ||
|
||
# Future work | ||
|
||
|
@@ -491,6 +485,10 @@ Since it was accepted, the RFC has been updated as follows: | |
2. `as` was changed to restore the behavior before the RFC (that is, | ||
it truncates to the target bitwidth and reinterprets the highest | ||
order bit, a.k.a. sign-bit, as necessary, as a C cast would). | ||
3. Shifts were specified to mask off the bits of over-long shifts. | ||
4. Overflow was specified to be two's complement wrapping (this was mostly | ||
a clarification). | ||
5. `INT_MIN / -1` and `INT_MIN % -1` panics. | ||
|
||
# Acknowledgements and further reading | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we guarantee this for platforms where arithmetic is not two’s complement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think LLVM supports anything other than two's complement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. We also don't acknowledged floating point rounding modes for similar reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually this is currently only the behavior when the operation cannot be constant evaluated. Even with checking disabled, const evaluatable cases will cause a compiler error. see #1229 for discussion