111/112: Add exercises for packed structs/unions

The first exercise introduces the `packed` keyword as an alternative for
bitwise operations. Its main goals are establishing a solid understanding
of field order and conveying the fact that packed containers are basically
integers.
It introduces the concept of container layouts and briefly explains the
default `auto` layout before introducing the `packed` layout (but doesn't
touch `extern` at all).
The exercise also presents a real-world use case for packed containers,
namely LZ4 frame descriptors.
Furthermore it covers equality comparisons between packed containers.

The second exercise talks about switch statements with packed containers
and goes into some more detail on packed unions.
This commit is contained in:
Justus Klausecker
2026-03-12 22:26:04 +01:00
parent 973ec41097
commit 16a794fbee
5 changed files with 350 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
--- exercises/111_packed.zig 2026-03-13 11:18:44
+++ answers/111_packed.zig 2026-03-13 11:18:57
@@ -41,7 +41,7 @@
const PackedStruct = packed struct {
a: u2,
- b: u?,
+ b: u4,
};
comptime {
@@ -50,7 +50,7 @@
const PackedUnion = packed union {
a: bool,
- b: u?,
+ b: u1,
};
comptime {
@@ -113,31 +113,31 @@
pub fn main() void {
{
const expected: Bits = @bitCast(@as(u4, 0b1000));
- const my_bits: Bits = .{};
+ const my_bits: Bits = .{ .d = 1 };
if (my_bits != expected) complain(my_bits, expected, @src());
}
{
const expected: Bits = @bitCast(@as(u4, 0b0001));
- const my_bits: Bits = .{};
+ const my_bits: Bits = .{ .a = 1 };
if (my_bits != expected) complain(my_bits, expected, @src());
}
{
const expected: Bits = @bitCast(@as(u4, 0b0010));
- const my_bits: Bits = .{};
+ const my_bits: Bits = .{ .b = 1 };
if (my_bits != expected) complain(my_bits, expected, @src());
}
{
const expected: Bits = @bitCast(@as(u4, 0b0011));
- const my_bits: Bits = .{};
+ const my_bits: Bits = .{ .a = 1, .b = 1 };
if (my_bits != expected) complain(my_bits, expected, @src());
}
{
const expected: Bits = @bitCast(@as(u4, 0b1101));
- const my_bits: Bits = .{};
+ const my_bits: Bits = .{ .a = 1, .c = 1, .d = 1 };
if (my_bits != expected) complain(my_bits, expected, @src());
}
}

View File

@@ -0,0 +1,32 @@
--- exercises/112_packed2.zig 2026-03-13 11:14:08
+++ answers/112_packed2.zig 2026-03-13 11:14:16
@@ -13,9 +13,9 @@
const s: S = .{ .a = true, .b = -1 };
switch (s) {
.{ .a = true, .b = -1 } => {}, // ok!
- .{ .a = true, .b = ??? },
- .{ .a = ???, .b = 0 },
- .{ .a = ???, .b = ??? },
+ .{ .a = true, .b = 0 },
+ .{ .a = false, .b = 0 },
+ .{ .a = false, .b = -1 },
=> @compileError("We don't want to end up here!"),
}
}
@@ -39,7 +39,6 @@
.{ .a = 3 } => {}, // ok!
.{ .a = 2 },
.{ .b = 1 },
- .{ .b = -1 },
.{ .a = 0 },
=> @compileError("We don't want to end up here!"),
}
@@ -65,7 +64,7 @@
// Reminder: if the sign bit of a float is set, the number is negative!
var number: Float = .{ .value = 2.34 };
- number.bits.??? = ???;
+ number.bits.sign = 1;
if (number.value != -2.34) {
std.debug.print("Make it negative!\n", .{});
}