zigo
1
In the following code, test 1 passed, but test 2 doesn’t.
const std = @import("std");
test "1" {
const T = union(enum) {
a: void,
b: u8,
};
const ts: [256]T = .{.a} ** 256;
std.debug.assert(ts[0] == .a);
}
test "2" {
const T = union(enum) {
a: bool,
b: u8,
};
const ts: [256]T = .{.a = false} ** 256;
std.debug.assert(ts[0] == .a);
}
1 Like
You’re only missing one more set of braces. You need to initialize the array with a union being initialized within that:
const ts: [256]T = .{ .{.a = false} } ** 256;
3 Likes
zigo
3
Aha, thanks! Interesting, I must miss something, why does test 1 pass?
That doesn’t even compile for me on godbolt - I get:
example.zig:10:29: error: coercion from enum '@TypeOf(.enum_literal)' to union 'example.bar__union_896' must initialize 'bool' field 'a'
Maybe someone else can run this in using zig test
and tell me what they get? Also, what Zig version are you on?
In the first test the a union type is not bool
, it is void
. In 0.12 it compiles, probably because .{.a}
is the same as .{a = {}}
1 Like
zigo
6
I use version 0.13.0-dev.8+c352845e8
.
This is the most unexpected zig syntax I have ever see.
test "2" {
const T = union(enum) {
a: bool,
b: u8,
};
const t: T = .{ .a = false };
const ts: [256]T = t ** 256;
std.debug.assert(ts[0] == .a);
}
fails with:
error: expected indexable; found 'test.test.2.T'
const ts: [256]T = t ** 256;
^
but t is already a T union.
EDIT: by changing t
to a single element array it becomes indexable.
test "2" {
const T = union(enum) {
a: bool,
b: u8,
};
const t = [1]T{T{ .a = false }};
const ts: [256]T = t ** 256;
std.debug.assert(ts[0] == .a);
}
2 Likes
Also, this is an important distinction about the void type. This compiles with void:
const ts: [256]T = .{.a} ** 256;
Because it’s interpreting the .{...}
as an array and then implicitly constructs a
. That’s a sneaky piece of syntax.
3 Likes
zigo
9
Do you mean .{.a}
is implicitly transformed to .{.{.a = {}}}
or .{.{.a = .{}}}
? (Really sneaky.)
Yeah, so…
.{..}
→ initialize array
.a
→ initialize void union member
Thus…
.{ .{ .a = void{} } }
1 Like
zigo
11
I do hope your old code
test "2" {
const T = union(enum) {
a: bool,
b: u8,
};
const t = T{ .a = false };
const ts: [256]T = t ** 256;
std.debug.assert(ts[0] == .a);
}
works.
Sze
12
I always use the 1 element array
const ts: [256]T = [1]T{ .{ .a = false } } ** 256;
4 Likes