-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Wrong warning?: literal out of range for i8 #48073
Comments
"all eight bits set to 1" is a valid bit pattern for i8, but the literal |
Thanks! Now I understand that the default type would be an unsigned integer and then there is a second step where a type casting happens and this is where the warning is raised. So this is clear to me and I would close the issue from my point of view. But then I looked for an alternative syntax, which would allow me to tell the compiler that my bit pattern is meant to be a signed integer and found my answer under "Literals and operators" in rust by example. Here it says:
OK, so I have changed That means to me, for my example above I should have used Unfortunatly, that didn't happen. I still get the warning. Now this has become a candidate for a different bug report, which could be just the following sentence: It seems to me that the type is taken into account if the literal is a decimal, but not in binary form. I haven't tried the hex form and other variable types, but this check would only makes sense after the |
Sorry, I'm not saying the I'd suggest just writing |
Or if you just want to specify " fn main() {
println!("-1 = {:b}", -1 as i8);
println!("0b11111111 = {}", 0b11111111 as u8 as i8);
} This has no warnings. |
Maybe the diagnostic could be improved in the presence of binary or hexadecimal representations. Since we lose the information about the original representation during AST generation we'll have to inspect the textual snippet though. |
In this case, I am afraid I have to disagree. If the syntax Unfortunatly, using an u8 as a dumb container of bits and then typecasting to i8 seems to work, but that doesn't help about the warning and that warning indicates to me that something behind the scenes is not working the way I thought and that might lead to a bug some day. @CAD97: Thanks for the workaround! Although I am happy that I can now achieve what I wanted, I am puzzled about this behaviour of the compiler. @rkruppe has explained why But, following the very same logic, |
This is covered by clippy (https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cast_sign_loss) as an allow-by-default lint because there are real use cases for interpreting a u8 that's bigger than |
A more clear cut example of this is Because Rust does guarantee two's complement, this is just a surface level disagreement (the worst that can happen to the code in the OP is that the lint becomes deny-by-default and even this is unlikely) but it's probably still easier to "go with the flow" and adopt Rust's interpretation. |
cc @flip1995 this seems like a good entry level diagnostic change to make to the compiler (improving the reported lint in the case of hex/binary representations) |
Yeah, I'd like to try this! But I'm not sure yet, what should be done here. I'm with @rkruppe , and think the warning is correct if you have an overflowing literal, regardless the representation. I think of something like |
While the warning is correct (and I, too, wouldn't change it), I think we should additionally produce a suggestion stating that if the user meant to create a literal with the exact bit representation, they should be doing $something_else
I think all hex/bin literals, no matter if explicit types are specified or not. |
I think we should add condensed version of @rkruppe's comment, along the lines of:
|
CC #24361 |
I think this is a nice help message. Should we additionally suggest a type where the literal fits into? e.g. |
What if the programmer intends to make a negative number? |
@mrhollow then they'll do so in an informed manner :) |
@estebank I respectfully disagree. I think if someone knows enough to set binary, they probably have a grasp on how it works, and throwing a warning that I have to override or work around each time I set the leftmost bit, seems a little over the top. Just my observation. |
@mrhollow the alternative would be a breaking change. I personally don't see a strong enough motivation to do that though. |
@mrhollow As has been hashed out extensively earlier in this issue, this is essentially a question of how integer literals are interpreted -- as natural numbers, of as a way to spell out a bit pattern. The policy Rust has chosen here requires some extra work in the case where a programmer both wants to construct a negative number and wants to do so by writing "bits" rather than some other means, but on the other hand notifies people that don't want that of their error (this includes actual overflow like |
@rkruppe Fair enough. :) |
Suggest type for overflowing bin/hex-literals Fixes rust-lang#48073 For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)). Additionally it will suggest a type (`X < Y`): - `iX`: if literal fits in `uX` => `uX`, else => `iY` - `-iX` => `iY` - `uX` => `uY` Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case. r? @oli-obk
Suggest type for overflowing bin/hex-literals Fixes rust-lang#48073 For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)). Additionally it will suggest a type (`X < Y`): - `iX`: if literal fits in `uX` => `uX`, else => `iY` - `-iX` => `iY` - `uX` => `uY` Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case. r? @oli-obk
Suggest type for overflowing bin/hex-literals Fixes rust-lang#48073 For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)). Additionally it will suggest a type (`X < Y`): - `iX`: if literal fits in `uX` => `uX`, else => `iY` - `-iX` => `iY` - `uX` => `uY` Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case. r? @oli-obk
Suggest type for overflowing bin/hex-literals Fixes rust-lang#48073 For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)). Additionally it will suggest a type (`X < Y`): - `iX`: if literal fits in `uX` => `uX`, else => `iY` - `-iX` => `iY` - `uX` => `uY` Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case. r? @oli-obk
I have this code:
Both lines return the expected result, namely
However, the compiler raises a warning as follows:
warning: src\main.rs:3: literal out of range for i8
note: src\main.rs:3: #[warn(overflowing_literals)] on by default
To my understanding,
0b11111111
is a valid signed integer and means -1 in decimal. Therefore the warning seems to be wrong to me.The text was updated successfully, but these errors were encountered: