Initialization of a field versus a decl of type [_]T

here’s an array-valued const of type [_]T which i declare as follows:

const table = [_]T { v1, v2, ... };

now, i want to define a struct type that has a similarly named field:

const S = struct {
    table: [_]T,
       ...
};

i then attempt to declare a const of type S as follows:

const s = S{
    .table = [_]T { v1, v2, ... },
        ...
};

but i receive compiler errors… what’s the correct way to express this initialization???

a related question is assigning a default value to the .table field… how do i express a zero-length array of type [_]T ???  alternatively, should i declare the type as ?[_]T and then use null as the default???

The issue here is that [_]T doesn’t have a length defined - it’s deduced based on the number of elements you declare it with. It’s an odd bit of syntax because the type doesn’t evaluate to [_] but instead becomes an array with a length when it’s deduced:

pub fn foo(_: [5]usize) usize {
    return 5;
}
export fn bar(_: i32) usize {
    const array = [_]usize{ 1, 2, 3 };
    return foo(array);
}

Returns the error:

example.zig:9:16: error: expected type '[5]usize', found '[3]usize'

So we can see that syntax doesn’t survive the assignment operation - it becomes [3]usize.

One option here is to take in a length parameter when you create this array:

pub fn foo(comptime T: type, comptime N: usize) type {
    return struct {
        table: [N]T,
        ...
    };
}

Then you could get:

const s = foo(i32, 3){
    .table = [_] i32 { 0, 1, 2 },
};

If you don’t know the length of the item and you want to keep it in a struct without having to pass a size parameter, your most direction option is to declare it as a slice []const T.

2 Likes

of course!!! this is the same problem as having array-valued fields in C struct (whose size must known at compile time)…

the slice type worked great… and i can use &.{} as its default value…

1 Like