I was recently solving Advent of Code 2015 Day 7 and I stumbled onto this little tiny rabbit hole. So, I have a struct called wire such as:
const Source = union(enum) {
id: [2]u8,
val: u16,
};
const Wire = struct {
id: [2]u8 = .{ ' ', ' ' },
val: ?u16 = null,
gate: enum(u8) { RShift, LShift, And, Or, Not, Value } = .Value,
lSrc: Source = .{ .val = 0 },
rSrc: Source = .{ .val = 0 },
};
Since I didn’t want to use a map because I’m allergic to STDs, I decided to create a big ass array and just iterate it over and over to search the wires. My first attempt at creating such array was a naive undefine:
var wires: [512]Wire = undefined;
Since undefined makes the memory layout be a 0101 pattern, my nullable value became very not null, which is not fun because I really need that value to be null since, later in the solution, it’s non-nullesness implies it has been set.
Then I tried:
var wires: [512]Wire = std.mem.zeroes([512]Wire);
Which fails at comptime because it Can't set a 15-07.Source to zero. I guess tagged unions can’t be zeroed…
Then I checked my ziglings exercises and found this weird syntax:
var wires: [512]Wire = [_]Wire{.{}} ** 512;
This does work, but it is really ugly.
Before you say it, yes, I know I can just @memset(std.mem.asBytes(&wires), 0); at runtime, but I wanted this to be done at comptime.
Some questions that I would appreciate an answer to would be:
How would you have written this?
Is there a simpler way to zero at comptime?
Am I expected to zero stuff at runtime?
Is there a way to zero a tagged union?
Why cant I just var wires: [512]Wire = zero;!?