-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Inconsistent behavior for bitshifts by more than length of field #1877
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
we use C/llvm semantics for shifts right now, which means that the results are undefined if a value is shifted by more bits than it possesses. In #1570 we discuss changing this to give guaranteed semantics (I think this would be a win). |
also, there is a big difference in the behavior depending on whether optimizations are enabled. |
I am confident in saying that boris is going to be performing toe-stubbing first-serious-use service on the bit-shift operators. Feel free to change them. They were have little more than a first coat of paint on 'em. |
For what it's worth, I don't personally plan to shift by more than width, so the exact behavior here is not a big deal for me, #1570 is a much bigger issue. |
Oh, I see, #1570 |
Er, yes. I meant #1570. |
Also undefined for negative values. |
This is still inconsistent. Updated the example: fn main() {
let i = 1u32 << 32u32;
println(fmt!("shift by literal 32, result: %d", i as int));
let mut s = 0u32;
while s < 40 {
let i = 1u32 << s;
println(fmt!("shift by variable %d, result: %d", s as int, i as int));
s = s + 1;
}
} |
I vote WONTFIX for perf concerns, but I'll bring this up at the meeting. |
We decided that this is not worth fixing out of performance concerns, as long as the undefined behavior is limited to the return value and won't cause anything memory-unsafe to happen. |
Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com>
Consider this testcase:
use std;
fn main() {
let i : u32 = (1u32 << 32u32);
std::io::println(#fmt("%d", i as int));
}
This prints 25187856 on my setup. If, on the other hand, I do something more like this:
use std;
fn main() {
let s : u32 = 0u32;
while (s < 40u32) {
let i : u32 = (1u32 << s);
std::io::println(
#fmt("shift: %d, result: %d", s as int, i as int));
s = s + 1u32;
}
}
then I get Java-like behavior; in particular one of the lines is:
shift: 32, result: 1
which totally doesn't match what happened with the shift by a literal!
The text was updated successfully, but these errors were encountered: