Search code examples
rustbooleanbit

Rust seems to allocate the same space in memory for an array of booleans as an array of 8 bit integers


Running this code in rust:

fn main() {
    println!("{:?}", std::mem::size_of::<[u8; 1024]>());
    println!("{:?}", std::mem::size_of::<[bool; 1024]>());
}

1024

1024

This is not what I expected. So I compiled and ran in release mode. But I got the same answer.

Why does the rust compiler seemingly allocate a whole byte for each single boolean? To me it seems to be a simple optimization to only allocate 128 bytes instead. This project implies I'm not the first to think this.

Is this a case of compilers being way harder than the seem? Or is this not optimized because it isn't a realistic scenario? Or am I not understanding something here?


Solution

  • Pointers and references.

    1. There is an assumption that you can always take a reference to an item of a slice, a field of a struct, etc...
    2. There is an assumption in the language that any reference to an instance of a statically sized type can transmuted to a type-erased pointer *mut ().

    Those two assumptions together mean that:

    • due to (2), it is not possible to create a "bit-reference" which would allow sub-byte addressing,
    • due to (1), it is not possible not to have references.

    This essentially means that any type must have a minimum alignment of one byte.


    Note that this is not necessarily an issue. Opting in to a 128 bytes representation should be done cautiously, as it implies trading off speed (and convenience) for memory. It's not a pure win.

    Prior art (in the name of std::vector<bool> in C++) is widely considered a mistake in hindsight.