How to construct a packed struct with some padding bytes?

i want to have a packed struct like:

const S = packed struct {
    a: u8,
    b: u8,
    padding: [510]u8
}

but the compiler complains that ‘packed structs cannot contain fields of type [510]u8’

how can i reconstruct this struct to make that @sizeOf(S) == 512 ?

although this

const S = packed struct {
    a: u8,
    b: u8,
    padding: u4080
}

works for now.
is there any other good idea?

Another way is to remove the padding and use an outer union:

const std = @import("std");

const S = packed struct {
    a: u8,
    b: u8,
};

const U = extern union {
    s: S,
    padding: [512]u8,
};

pub fn main() void {
    const u = U{ .s = S{ .a = 0, .b = 1 } };
    std.debug.print(
        \\u.s={any}
        \\sizeof(U)={d}
        \\
    , .{
        u.s,
        @sizeOf(U),
    });
}
3 Likes

extern struct follows the C ABI, so I use it for structs with well-defined padding locations:

const S = extern struct {
    a: u8,
    b: u8,
    padding: [510]u8 = undefined
};

test "S properties" {
    const assert = @import("std").debug.assert;
    assert(@sizeOf(S) == 512);
    const s = S{ .a = 1, .b = 2 };
    assert(s.a == 1);
    assert(s.b == 2);
}
3 Likes

:+1:
both worked. so is extern a better packed?

It is different:

  • extern means use the C ABI for the target platform, you can also use align(1) to ensure no padding between elements:

    const S = extern struct {
        a: u8 align(1),
        b: u8 align(1),
        padding: [510]u8,
    };
    
  • packed have guarantee memory layout (order) without padding between elements.

3 Likes

If you are coming from C:

Packed struct in zig is different than attribute packed in C compilers. Packed struct in c compiler is closer to an extern struct in zig with align(...) on all the fields.

https://ziglang.org/documentation/master/#Alignment

1 Like

We really need more info about this in the langref