1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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);
}
}
|