Hi.
Here is simple program.
$ cat p1.zig
const std = @import("std");
const Object = struct {
a: i32 = 7,
b: i32 = 8,
};
pub fn main() void {
const len = 3;
var arr: [len]Object = [_]Object{.{}} ** len;
std.debug.print("\n{any}\n", .{arr});
}
It works as expected:
$ ./p1
{ p1.Object{ .a = 7, .b = 8 }, p1.Object{ .a = 7, .b = 8 }, p1.Object{ .a = 7, .b = 8 } }
However when I indicated the length of the array in initializer explicitly I got this:
$ /opt/zig/zig build-exe p1.zig
p1.zig:11:39: error: expected 3 array elements; found 1
var arr: [len]Object = [len]Object{.{}} ** len;
~~~~~~~~~~~^~~~~
It seems I do not understand something…
Why does explicit array length in initializing part causes this error?
could be a bug, did you try searching for issues?
No, I did not. I thought it would be better to ask here first before reporting a bug.
len is definitely comptime known, so it seems pretty obvious it is a bug. but i don’t see one when i search the issues.
no, i’m afraid it is not a bug but just a very confusing error message.
in the doc, the examples all show an empty array len [_] in initializers, so apparently that is the syntax for initializers, even though this is never stated explicitly
oops… I’ve already reported this as a bug (here). Ok, let’ see.
Yes, that means compiler will infer the length, if I get it right. But anyway I do not understand why explicit length results in such a strange error message. Where did compiler see one array element?
= [_] Object{.{}} ** 3;
= [3] Object{.{}} ** 3;
These two have absolutely the same look for me.
Probably the compiler treats the second one as one element, which is 3-element (or 9-element???) array by itself.
This variant is ok:
const std = @import("std");
const Object = struct {
a: i32 = 7,
b: i32 = 8,
};
pub fn main() void {
const len = 3;
var arr: [len]Object = [len]Object{.{}, .{}, .{}};
std.debug.print("\n{any}\n", .{arr});
}
So it’s not explicit length in initializer, it’s length plus duplication (**
).
As was explained to me, the point is that
[_]Object{.{}} ** len
means
([1]Object{.{}}) ** len
4 Likes