Choosing alignment with the repr attribute

Minimum Rust version: 1.25

From Wikipedia:

The CPU in modern computer hardware performs reads and writes to memorymost efficiently when the data is naturally aligned, which generally meansthat the data address is a multiple of the data size. Data alignment refersto aligning elements according to their natural alignment. To ensure naturalalignment, it may be necessary to insert some padding between structureelements or after the last element of a structure.

The #[repr] attribute has a new parameter, align, that sets the alignment of your struct:

  1. #![allow(unused_variables)]
  2. fn main() {
  3. struct Number(i32);
  4. assert_eq!(std::mem::align_of::<Number>(), 4);
  5. assert_eq!(std::mem::size_of::<Number>(), 4);
  6. #[repr(align(16))]
  7. struct Align16(i32);
  8. assert_eq!(std::mem::align_of::<Align16>(), 16);
  9. assert_eq!(std::mem::size_of::<Align16>(), 16);
  10. }

If you’re working with low-level stuff, control of these kinds of things canbe very important!

The alignment of a type is normally not worried about as the compiler will"do the right thing" of picking an appropriate alignment for general usecases. There are situations, however, where a nonstandard alignment may bedesired when operating with foreign systems. For example these sorts ofsituations tend to necessitate or be much easier with a custom alignment:

  • Hardware can often have obscure requirements such as "this structure isaligned to 32 bytes" when it in fact is only composed of 4-byte values. Whilethis can typically be manually calculated and managed, it's often also usefulto express this as a property of a type to get the compiler to do a littleextra work instead.
  • C compilers like gcc and clang offer the ability to specify a customalignment for structures, and Rust can much more easily interoperate withthese types if Rust can also mirror the request for a custom alignment (e.g.passing a structure to C correctly is much easier).
  • Custom alignment can often be used for various tricks here and there and isoften convenient as "let's play around with an implementation" tool. Forexample this can be used to statically allocate page tables in a kernel orcreate an at-least cache-line-sized structure easily for concurrentprogramming.

The purpose of this feature is to provide a lightweight annotation to alterthe compiler-inferred alignment of a structure to enable these situationsmuch more easily.