Packed struct is larger than normal struct

const t2 = packed struct {
    v1: u32,
    v2: u32,
    v3: u32,
    v4: u32,
    v5: u32,
    v6: u32,
    v7: u32,
    v8: u32,
    v9: u32,
    v10: u32,
};

const t1 = struct {
    v1: u32,
    v2: u32,
    v3: u32,
    v4: u32,
    v5: u32,
    v6: u32,
    v7: u32,
    v8: u32,
    v9: u32,
    v10: u32,
};

sizeof(t1) is 40
sizeof(t2) is 48
I am a bit confused why it is larger?

I saw a few other posts about odd sizing of packed structs which seemed related to odd sized number of bytes / bits 40 is already an even number

I saw there is extern struct which just ends up being the same size as the normal struct in my case (which im not sure what its supposed to do)

The reason for this is similar to the other posts I have seen. I have some []u8 (byte array) which I want to @ptrCast into a struct (compiler also wants @alignCast so I added that as well) is there a easy way to do this in zig? which can be somewhat common in c. I would honestly prefer if I didnt have to make it packed but I assume there is not an easy way around that and I want to take the easy path right now rather than parsing a bunch of numbers from a byte array

Should I cast into a u32 array first then into the struct?

This is not a bug, more like an implementation detail.
idk if it will be changed or not in the future as it this detail isn’t specified in the reference and the language spec only contains grammar atm.

matklad described packed structs as an integer in a fancy hat which at least currently is exactly how it’s implemented.

A packed struct is put into an integer with the bit size the struct requires, your example would be u320. Integers get rounded up to the nearest byte size, 320 already meets that requirement.

However, it does not have a valid alignment, in this case its 40, alignment has to be a power of 2, the next power of 2 is 48 so it gets rounded up to that and its size increases as a consequence
edit: integers above u64 are required to have an alignment of 16, the nearest alignment of 16 is 48

Confusion comes from multiple facts

  • packed structs are integers
  • any integer which is larger than u64 would be 16 aligned
  • sizeof for integers is divisible by alignment

If we sum all field sizes we will get 40. But 40 is not 16 divisible so we round it to 48 for it to be divisible.

7 Likes