diff options
Diffstat (limited to 'lang/zig/struct-packed.zig')
-rw-r--r-- | lang/zig/struct-packed.zig | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lang/zig/struct-packed.zig b/lang/zig/struct-packed.zig new file mode 100644 index 0000000..f493661 --- /dev/null +++ b/lang/zig/struct-packed.zig @@ -0,0 +1,73 @@ +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); + } +} |