Skip to content
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

Inconsistent behavior for bitshifts by more than length of field #1877

Closed
bzbarsky opened this issue Feb 21, 2012 · 11 comments
Closed

Inconsistent behavior for bitshifts by more than length of field #1877

bzbarsky opened this issue Feb 21, 2012 · 11 comments
Labels
A-codegen Area: Code generation

Comments

@bzbarsky
Copy link

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!

@nikomatsakis
Copy link
Contributor

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).

@nikomatsakis
Copy link
Contributor

also, there is a big difference in the behavior depending on whether optimizations are enabled.

@graydon
Copy link
Contributor

graydon commented Feb 21, 2012

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.

@bzbarsky
Copy link
Author

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.

@brson
Copy link
Contributor

brson commented Feb 21, 2012

@bzbarsky is #1750 really the issue that you are concerned about, or was that a typo?

@brson
Copy link
Contributor

brson commented Feb 21, 2012

Oh, I see, #1570

@bzbarsky
Copy link
Author

Er, yes. I meant #1570.

@brson
Copy link
Contributor

brson commented Feb 23, 2012

Also undefined for negative values.

@bstrie
Copy link
Contributor

bstrie commented Apr 26, 2013

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;
    }
}

@pcwalton
Copy link
Contributor

I vote WONTFIX for perf concerns, but I'll bring this up at the meeting.

@pcwalton
Copy link
Contributor

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.

celinval pushed a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com>
Kobzol pushed a commit to Kobzol/rust that referenced this issue Dec 30, 2024
bors pushed a commit to rust-lang-ci/rust that referenced this issue Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation
Projects
None yet
Development

No branches or pull requests

6 participants