maximxls
maximxls

Reputation: 63

Why doesn't converting a u8 pointer into a [bool; 8] pointer yield the number bit-by-bit?

I'm experimenting with raw pointers in Rust. I have the following code:

fn main() {
    let mut t: u8 = 0;

    let addr = &mut t as *mut u8 as usize;

    let x = addr as *mut [bool; 8];

    let y = addr as *mut u8;
    unsafe {
        *y = 0b10101010;
        println!("{:?} {:b}", *x, *y);
    }
}

It produces the following output: [true, true, true, true, true, true, true, false] 10101010 while I expect it to print [true, false, true, false, true, false, true, false] 10101010. What is going on? Isn't bool array stored bit by bit?

Upvotes: 1

Views: 1021

Answers (1)

loops
loops

Reputation: 5635

The behavior of that program is undefined (so the output is meaningless). From Miri:

error: Undefined Behavior: memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc1381 which has size 1
  --> src/main.rs:11:31
   |
11 |         println!("{:?} {:b}", *x, *y);
   |                               ^^ memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc1381 which has size 1
   |
   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

Boolean arrays are stored byte-by-byte, not bit-by-bit. Use the bitvec or bitfield crate if you want bit-by-bit storage. There is no way for a pointer to point to an individual bit: pointers always point to bytes (pointers to bits aren't supported by basically any ISAs). bools are 1 byte long, and cannot safely have any value other than 0_u8 or 1_u8.

Upvotes: 5

Related Questions