Search code examples
zig

Can't use .len of a bidimensional array


I have this simple code that doesn't compile.

const s = [_][_]int {
    [_]int{08, 02, 22, 97, 38, 15, 00},
    [_]int{49, 49, 99, 40, 17, 81, 18},
    [_]int{81, 49, 31, 73, 55, 79, 14},
    [_]int{52, 70, 95, 23, 04, 60, 11},
    [_]int{22, 31, 16, 71, 51, 67, 63},
    [_]int{24, 47, 32, 60, 99, 03, 45},
    [_]int{32, 98, 81, 28, 64, 23, 67},
    [_]int{67, 26, 20, 68, 02, 62, 12},
    [_]int{24, 55, 58, 05, 66, 73, 99},
    [_]int{21, 36, 23, 09, 75, 00, 76}
};

pub fn main() void
{
    const w = s[0].len;
    const h = s.len;
}

The compiler says:

./a.zig:1:14: error: inferred array size invalid here
const s = [_][_]int {
             ^
./a.zig:16:15: note: referenced here
    const w = s[0].len;

What is the problem?


Solution

  • I'd be interested to know there's a deeper reason, but my simple understanding is that the current syntax [N]T allows for the array size to be elided using _, but not for more than one dimension.

    So you can fix your problem using the following (N.B. I've used u8 because I'm unsure what your int is):

    const s = [_][7]u8{
      // Your items
    }
    

    I suspect this is because of the way the parsing rules are applied, so [7]u8 would be the type your nested array would hold, and will be used by the compiler to check contents are all of type [7]u8; you can confirm this by modifying one of your rows to have 6 elements and examining the resulting error.

    If you want a variable number of items, you could start to look into an array of slices: [_][]u8, but I don't think that's what you're currently after.