Consider that I have a packed struct with underlying backing integer u112
(14 bytes).
On my system, this packed struct will align to u128
(16 bytes).
How do I obtain a slice of only the bytes used by the packed struct without the padding bytes?
Consider that I have a packed struct with underlying backing integer u112
(14 bytes).
On my system, this packed struct will align to u128
(16 bytes).
How do I obtain a slice of only the bytes used by the packed struct without the padding bytes?
@bitSizeOf(T) returns the actual bits used by a packed struct.
To get the bytes you need to ceiling divide by 8.
Which bytes are the paddings bytes? Is it always highest address or most significant bytes?
The first member of the packed struct is in the first bytes or least significant bytes.
The padding bytes are the remaining last bytes or most significant bytes.
This should help answer your question:
const P112 = packed struct(u112) {
a: u64 = 0, // eight
b: u32 = 0xaaaaaaaa, // four (twelve)
c: u8,
d: u8,
};
test "packed unpacking" {
std.debug.print("size of P112: {d}\n", .{@sizeOf(P112)});
std.debug.print("bit size of P112: {d}\n", .{@bitSizeOf(P112)});
const a_p112 = P112{ .c = 0x11, .d = 0xcc };
const a_bytes = std.mem.asBytes(&a_p112);
std.debug.print("byte length of cast P112: {d}\n", .{a_bytes.len});
const a_real_bytes = a_bytes[0 .. 112 / 8];
try std.testing.expectEqual(0xcc, a_real_bytes[a_real_bytes.len - 1]);
}
Im not sure these solutions will work on big endian systems.
On a big endian system, the least significant bytes have the highest address (and thus are the last elements in a slice)
Unlike normal structs, packed structs have guaranteed in-memory layout:
- Fields remain in the order declared, least to most significant.
- There is no padding between fields.
- …
In big endian systems the order of the fields remain the same (least to most significant), but the order of bytes in fields change.