Designator lists for field initialization

If you have nested structs/unions, for example

const Foo = struct { value: u32 };
const Bar = union { foo: Foo, notfoo: u8 };
const Baz = struct { bar: Bar, has_a_default: u32 = 0 };

and want to initialize only one field of each, in Zig you still have to write nested braces for each level:

const baz: Baz = .{ .bar = .{ .foo = .{ .value = 42 } } };

For comparison, C has designator lists (see 6.7.11 Initialization in the C standard), which means you can do what in Zig would be

const baz: Baz = .{ .bar.foo.value = 42 }; // does not work

I think this would be much nicer and easier to read. Has something like this already been discussed? It would also be useful for zon files, I think toml has a similar shortcut.

As far as I can tell, the syntax change for this would be small and not cause any problems/ambiguities. Just replace FieldInit <- DOT IDENTIFIER EQUAL Expr in the grammar with something like

FieldInit <- DesignatorList EQUAL Expr
DesignatorList <- DesignatorList DOT IDENTIFIER / DOT IDENTIFIER

I bet the Zig team is sick and tired by now hearing about how awesome C99 designated init is, and I’m probably responsible for that :wink:

I guess some of the features that make C99 designated init so damn convenient will collide with the way the Zig parser works and how types are inferred. IMHO I would prioritize convenience and readability over ‘conceptual purity’, but I also understand that this philosophy can be dangerous and turn the language into a kitchen-sink.

Still, C99 designated init is the coolest thing since sliced bread, and I’m still sad that this got closed (another nice C99 designated init feature): QoL: Partial array initialization in structs · Issue #6068 · ziglang/zig · GitHub

2 Likes