Size of product types

I don't know that much about alignment and how sizes are determined, so I was looking into it.
One question I have is:
Why does size_of::<(usize,i32)>() == size_of::<(usize,usize)>(), but != size_of::<([u8;8],usize)>()?

println!("{}", mem::size_of::<(&i32,i32)>());       //16
println!("{}", mem::size_of::<(usize,i32)>());      //16 //Why not 12?
println!("{}", mem::size_of::<([u8;8],i32)>());     //12 //Why not 16?
  • &i32 and usize are 8 bytes and aligned to 8 bytes
  • i32 is 4 bytes and aligned to 4 bytes
  • u8 is 1 byte and aligned to 1 byte
  • [T; N] is sizeof(T) * N bytes and aligned to alignof(T)


  • [u8; 8] is 8 bytes and aligned to 1 byte

Product types generally have the same size as the sum of their parts rounded up the the max align of their fields, so

  • (&i32, i32) and (usize, i32) has size 12 rounded up to align of 8, which means actual size of 16
  • ([u8; 8], i32) has size 12 rounded up to align of 4, which means actual size of 12

If you want to really get in to the details of this see The Lost Art of Structure Packing.

The pithy slogan version (which skips the details) is: "the size of a type must be a multiple of its alignment". This makes it easy to index properly aligned types in arrays.

Though do note that Rust, unlike C, is free to automatically reorder the fields in structures to be more performant. And of course types where size == 0 are special.

1 Like

Another thing to mention is that tuples can be thought of as syntactic sugar for structs. So (usize, i32) is represented as

struct UsizeAndI32 {
    _0: usize,
    _1: i32,

And because there aren't any specifiers around layout (i.e. UsizeAndI32 is considered Repr(Rust)), the compiler is free to rearrange fields or insert padding as it sees fit. At the moment I think the only interesting layout tweaks it'll do is the null pointer optimisation (a form of "niche" optimisation), though.

If you haven't already found it, the Type Layout chapter in The Rust Reference may be useful.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.