Extra capture in for loop

I am copying bytes from one array to another:

const std = @import("std");
const print = std.debug.print;

pub fn main() void {
    const s1: [3]u8 = .{1,2,3};
    var s2: [3]u8 = .{0,0,0};

    for (s1) |x, k| {
        s2[k] = x;
    }

    print("{any}\n", .{s2});
}

With zig 0.10 the program works as was intended:

$ ./c
{ 1, 2, 3 }

With zig 0.11 and 0.12 I got an error:

$ /opt/zig-0.12/zig build-exe c.zig 
c.zig:9:18: error: extra capture in for loop
    for (s1) |x, k| {
                 ^

It looks like zig 0.11/0.12 does not want to use k for indexing an array that is not in for()
What can I do with this?

I’d add the 0.. to declare it as an index capture:

  for (s1, 0..) |x, k| {
      s2[k] = x;
  }
1 Like

Ah, ok, it’s easy, thanks!

BTW, zig 0.11 has a hint:

c.zig:9:18: note: run 'zig fmt' to upgrade your code automatically

This adds missing 0.. into the for

zig 0.12 for some reason does not have this tip.

You can also write your loop like this, and take advantage of the compiler checking that both arrays are the same size:

    for (s1, s2) |src, *tgt| {
        tgt.* = src;
    }
7 Likes

zig fmt does not do anything.
zig fmt src/main.zig does someting, but does not any upgrade… only says:

src/main.zig:232:24: error: extra capture in for loop
    for (slice) |item, i| {

in 0.13

I think this may have been an exclusive feature of Zig v0.11 to help with migrations from v0.10.

2 Likes

https://ziglang.org/download/0.11.0/release-notes.html#Multi-Object-For-Loops