38 ms·
Anybody knows how Rust handles this problem?
by d33 10y ago
Anybody knows how Rust handles this problem?
- alkonaut 10y agoNot 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.
- wyldfire 10y agoI 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()
- alkonaut 10y agoThe 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).
- Thiez 10y agoThe 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.
- alkonaut 10y agoHmm, 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; }
- steveklabnik 10y agoStructs 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>()); }
- alkonaut 10y agoWhat 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).
- steveklabnik 10y agoAh! 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.
- Thiez 10y agoWell given that Rust leaves struct layout undefined unless #[repr(C)] is specified, std::mem::size_of::<Three> is actually not guaranteed to be 4.
- steveklabnik 10y agoWhile 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...
- hsivonen 10y agoTypes in Rust have alignment as in C, and bad stuff may happen if you use unsafe code to violate alignment. It seems that at present, if you want to generate an unaligned SSE2 load/store, you have to rely on modern memcpy (spelled copy_nonoverlapping in Rust) optimization. See the first reply to https://internals.rust-lang.org/t/unaligned-simd-sse2-in-particular-loads-stores/4336 https://internals.rust-lang.org/t/unaligned-simd-sse2-in-par...