News for hackers. Stuff that matters.
Re:A bug story: data alignment on x86 by alkonaut on Monday November 07, 2016 @08:57AM (#12890994)
Not sure if this is what you are asking: Last time I tried alignment in Rust I worked around the lack of explicit alignment support by adding a zero length array of the correct size to the end of the struct. Not sure if alignment support from proper attributes has landed yet.

   [repr(C)]
   struct Something
   {
      pub foo: f32,
      pub _alignment: [EightBytes, 0]
   }
where "EightBytes" is a data type of size 8, to align the whole struct on 8 bytes.
Re:A bug story: data alignment on x86 by steveklabnik on Monday November 07, 2016 @09:34AM (#12891240)
Structs already insert padding to give them alignment:

    struct One {
      foo: u8,
    }
    
    struct Two {
      bar: u16,
    }
    
    struct Three {
      foo: u8,
      bar: u16,
    }
    
    struct Four {
      foo: u16,
      bar: u16,
    }
    
    fn main() {
        assert_eq!(1, std::mem::size_of::<One>());
        assert_eq!(2, std::mem::size_of::<Two>());
        assert_eq!(4, std::mem::size_of::<Three>());
        assert_eq!(4, std::mem::size_of::<Four>());
    }
Re:A bug story: data alignment on x86 by alkonaut on Monday November 07, 2016 @09:43AM (#12891325)
What I needed to do was to place e.g. a N byte struct exactly on an M byte alignment (e.g. 11 byte struct on 32 byte alignment etc).
Re:A bug story: data alignment on x86 by steveklabnik on Monday November 07, 2016 @10:10AM (#12891616)
Ah! Yeah, that's different, and as far as I know your way is the current right way to do it, but I'm not an expert on the subject.
Re:A bug story: data alignment on x86 by Thiez on Monday November 07, 2016 @01:49PM (#12893699)
Well given that Rust leaves struct layout undefined unless #[repr(C)] is specified, std::mem::size_of::<Three> is actually not guaranteed to be 4.
Re:A bug story: data alignment on x86 by steveklabnik on Monday November 07, 2016 @02:01PM (#12893824)
While this is true, it's a weird angle that's not itself super well defined. That is, the definition of repr(packed) implies that the alignment will always be there without it...
Re:A bug story: data alignment on x86 by wyldfire on Monday November 07, 2016 @09:13AM (#12891084)
I doubt you can count on all items being allocated at addresses that are multiples if their size.

It's not optimal but you can always use libc::posix_memalign()

Re:A bug story: data alignment on x86 by alkonaut on Monday November 07, 2016 @02:50PM (#12894350)
The final element of the struct is a zero length array of elements of size N bytes. So that element isn't padding, it has size 0! It's pure hinting. I'm not sure why or how this works under the hood I'm afraid. I used it successfully to call a library with pretty strict alignment requirements (Intel Embree).
Re:A bug story: data alignment on x86 by Thiez on Monday November 07, 2016 @05:37PM (#12895879)
The zero length array still must be aligned correctly. You can create a pointer to it (e.g. by taking &something._alignment[..] to create a slice) and pointers must have correct alignment, so it follows that a zero length array has the same alignment requirements as a longer array. So padding must be inserted in your struct so that the address of the zero-length array is correctly aligned.
Re:A bug story: data alignment on x86 by alkonaut on Tuesday November 08, 2016 @06:29AM (#12899358)
Hmm, I don't understand (sorry). The pointer to the internal array must be aligned. But how does the element size play into the padding. If we take these two examples?

   [repr(C)]
   struct StructA
   {
      pub foo: f32,
      _alignment: [SixteenBytes, 0]
   }

   [repr(C)]
   struct StructB
   {
      pub foo: f32,
      _alignment: [ThirtytwoBytes, 0]
   }
Are both just padded with 16-4 and 32-4 bytes respectively, so they are equivalent to making a padding like this in the first case?

   [repr(C)]
   struct StructAPadded
   {
      pub foo: f32,
      _padding : TwelveBytes;
   }