Why can't I provide default values for tagged union?

Recently, I wanted to specify default values for a tagged union but got some strange error messages:

const Foo = struct {
    bar: union(enum) {
        f1: ?bool = null,
        f2: ?bool = null,
    },
};

Throws:

howtos/q_taggedUnionDefVal.zig:4:10: error: explicitly valued tagged union missing integer tag type
    bar: union(enum) {
         ^~~~~
howtos/q_taggedUnionDefVal.zig:5:21: note: tag value specified here
        f1: ?bool = null,
                    ^~~~

Changing union(enum) to enum(u1) or to a separately defined enum throws something contradictory:

error: explicitly valued tagged union requires inferred enum tag type

I found an open issue, Incorrect error when assigning default value to tagged union in struct · Issue #14561 · ziglang/zig · GitHub, that reports the error message is indeed confusing. I thought this is a compiler bug, but after I looked closely, the issue says that it is just the error message that is incorrect, not the behavior of the compiler itself, and it should have reported something like “error: unions do not support default values” instead. Are default values for tagged unions not going to be supported? If so, why?

How would you expect default union fields to work? For structs it’s simple, you just do .{} and all fields get initialized, this makes intuitive sense to write and is easy for the compiler to parse.
But for unions we need a tag field Union{.tag = value}. Should a new syntax be introduced for a feature like this that almost no one will actually use?

4 Likes

Ok, I think I asked a bit silly question :blush:. I can’t because there is no way to decide which field is going to be initialized. So what I needed is just to move the defaults in the right place:

const Foo = struct {
    bar: union(u1) {
        f1: ?bool,
        f2: ?bool,
    } = .{ .f1 = true },
};
8 Likes