const std = @import("std"); const endian = std.builtin.endian; const expect = std.testing.expect; const Full = packed struct { number: u16, }; const Divided = packed struct { half1: u8, quarter3: u4, quarter4: u4, }; fn doTheTest() void { expect(@sizeOf(Full) == 2); expect(@sizeOf(Divided) == 2); var full = Full{ .number = 0x1234 }; var divided = @bitCast(Divided, full); switch (endian) { .Big => { expect(divided.half1 == 0x12); expect(divided.quarter3 == 0x3); expect(divided.quarter4 == 0x4); }, .Little => { expect(divided.half1 == 0x34); expect(divided.quarter3 == 0x2); expect(divided.quarter4 == 0x1); }, } } test "@bitCast between packed structs" { doTheTest(); comptime doTheTest(); } const BitField = packed struct { a: u3, b: u3, c: u2, }; var foo = BitField{ .a = 1, .b = 2, .c = 3, }; fn bar(x: *const u3) u3 { return x.*; } test "pointer to non-byte-aligned field" { const ptr = &foo.b; expect(ptr.* == 2); // The pointer to a non-byte-aligned field has special properties // and cannot be passed when a normal pointer is expected: // expect(bar(ptr) == 2); // Here's why: expect(@ptrToInt(&foo.a) == @ptrToInt(&foo.b)); expect(@ptrToInt(&foo.a) == @ptrToInt(&foo.c)); comptime { expect(@bitOffsetOf(BitField, "a") == 0); expect(@bitOffsetOf(BitField, "b") == 3); expect(@bitOffsetOf(BitField, "c") == 6); expect(@byteOffsetOf(BitField, "a") == 0); expect(@byteOffsetOf(BitField, "b") == 0); expect(@byteOffsetOf(BitField, "c") == 0); } }