The following code works correctly with Rust 1.8 on amd64.
use std::mem;
fn main() {
let f: u8 = unsafe { mem::transmute(false) };
let t: u8 = unsafe {
The bool representation seems to be very strict. It is represented as 1 and 0, but I'd like to caution that if for some insane reason this changes you'll get some strange behavior if you blindly assume that true == <some u8 that isn't what Rust really uses>
. This is the opposite direction to your question, but I think it makes a point:
fn main() {
use std::mem;
let b: bool = unsafe {mem::transmute(4 as u8)};
println!("{} {} {}", b, b == true, b == false);
if b {
println!("evaluates true");
}
if !b {
println!("evaluates false");
}
let x: u8 = unsafe{mem::transmute(b)};
println!("{}", x);
let x = b as u8;
println!("{}", x);
}
This produces a different output on nearly every configuration on that Playground I tested it on. With frequent flat out contradictions within the same program:
true true true
evaluates false
0
0
This means it prints as true, compares as true with both true and false, but evaluates in a branch as false. And transmutes back to 0.
true false true
evaluates true
4
4
This is probably what you'd "expect" if you were using a C-style bool, and has the correct transmute behavior. (Edit: actually, no it's not. It prints wrong! It compares the opposite to how it evaluates).
true true true
evaluates false
4
4
Same as Debug/Stable, but transmutes back correctly (I assume this was probably a bug that got fixed).
Same as Release/Stable
Same as Debug/Beta
Same as Release for others.
If you change println!("{} {} {}", b, b == true, b == false);
to println!("{} {}", b, b == true);
you get different printing behavior.
For instance, on Debug/Stable:
true false
evaluates false
0
0
In addition, transmuting from 1 as u8
works as expected on all configurations, so it's not solely a transmute
issue.
The moral of the story is that, while this is unlikely to change, you potentially have one hell of a Heisenbug on your hands if it does (or you make a mistake with the u8 and transmute it back or change it with an unsafe pointer). For most cases, I'd probably just stick with the perfectly working and safe my_bool as u8
, though I understand your use case may prohibit this.
There was never any RFC adopted defining the representation of bool
. That said, as a practical matter it's very unlikely it will change.