#[repr(align(32))] how this statement change the behaviour of below program

struct S(u8);

fn main() {

    println!("size of S: {}", std::mem::size_of::<S>());
    println!("align of S: {}", std::mem::align_of::<S>());
}

//what is the difference between above code //and this one

#[repr(align(32))]
struct S(u8);

fn main() {

    println!("size of S: {}", std::mem::size_of::<S>());
    println!("align of S: {}", std::mem::align_of::<S>());
}

Why don't you run it and see? :wink:

2 Likes

In above first program it shows 1 byte.
Second program shows 32 bytes.

My understand is second program takes 32 bytes space to store struct S.

Is right?

Yes. The size of a type is always a multiple of its alignment. S(u8) on its own has an unstable layout, but realistically, the compiler will most likely give it size 1 and alignment 1 (in bytes). Adding #[repr(align(32))] means that alignment will be increased if it wasn't at least 32 yet.

Alignment 32 of a data type means that every value of that type will start at a memory address that's a multiple of 32. The 31 extra bytes are padding and contain no data, but they take up space: E.g. an array/slice β€œ[S]” of these S's

#[repr(align(32))]
struct S(u8);

is consisting mostly of padding: 1 byte of data, then 31 bytes of padding, then 1 byte of data again, etc., and this makes sure that each data byte has an address that's a multiple of 32. [1]

Increasing the alignment like this can sometimes make sense to make sure values land on different cache lines to make parallel code more efficient; or it could, together with repr(C), make sense if you need to conform to some ABI to control layout more precisely. (And there's probably other use-cases I can’t think of right now.) Other than that, it's mostly a disadvantage, because it increases memory consumption, so don't use #[repr(align(32))] unless you know why you need it.


  1. As noted above, the layout is actually unstable. This applies to the repr(align(32)) case, too, AFAIK; without an additional repr(C) (or something similar), the rust compiler could – in theory – also decide to make the struct even larger, though that seems pretty unlikely to actually ever happen. β†©οΈŽ

5 Likes

The only other thing that I can see would require this would be using vector extensions on architectures (e.g. AVX, SSE, SSSE, AVX2, etc.). These extensions usually have alignment requirements of one kind or another, and they're usually enforced.