bitfield-struct-rs icon indicating copy to clipboard operation
bitfield-struct-rs copied to clipboard

Hashing of bitfield structs with unused space/padding

Open freemin7 opened this issue 7 months ago • 2 comments

Assuming i have stuct with padding.

#[bitfield(u8)]
#[derive(Hash)]
struct MyBitfield {
    #[bits(4)]
    cnt: u8,
    #[bits(2)]
    type: u8,
    /// Padding
    #[bits(2)]
    __: u8,
}

It is currently not documented whether hashing done on this type will depend on the data in padding or not. I think hashing is something that should be considered and documented. As i am new to Rust i am not confident that i can come to any conclusion on this. If my experimentation yields a definite result i will share my findings.

I learned that i look at derive expaned code. Expanding this yield something like:

#[automatically_derived]
impl ::core::hash::Hash for MyBitfield {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.0, state)
    }
}

This is confirmed by this experiment:

  let mut hasher = DefaultHasher::new();
  MyBitfield::from_bits(0b01010101).hash(&mut hasher);
    
  let mut hasher2 = DefaultHasher::new();
  MyBitfield::from_bits(0b00010101).hash(&mut hasher2);

  assert_eq!(hasher.finish(), hasher2.finish()); // asserts 

It seems to access the entire u8, which includes the padding. Whether the padding is initialized in a well defined way, is not something i am yet aware off. I am also uncertain what operations are safe (e.g do not modify the padding) or if there are any guarantees. The docs do not specify this.

freemin7 avatar Mar 05 '25 11:03 freemin7