🔧

Zig言語のmasterの@memset, @memcpyの仕様が変更された

2023/04/29に公開

Github actions のZigのmaster版を使ったビルドが突如エラーに

2023/04/29 にそれまで問題のなかったzig buildが以下のようなエラーになってしまいました。

Build Summary: 0/3 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
└─ install v4l2capture transitive failure
   └─ zig build-exe v4l2capture Debug native 4 errors
src/v4l2capture.zig:88:9: error: expected 2 arguments, found 3
        @memset(@ptrCast([*]u8, &fmt), 0, @sizeOf(c.struct_v4l2_format));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/v4l2capture.zig:111:9: error: expected 2 arguments, found 3
        @memset(@ptrCast([*]u8, &streamparm), 0, @sizeOf(c.struct_v4l2_streamparm));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/v4l2capture.zig:133:9: error: expected 2 arguments, found 3
        @memset(@ptrCast([*]u8, &req), 0, @sizeOf(c.struct_v4l2_requestbuffers));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/v4l2capture.zig:157:9: error: expected 2 arguments, found 3
        @memset(@ptrCast([*]u8, &buf), 0, @sizeOf(c.struct_v4l2_buffer));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

手元のzig を以下のものにアップデートしたら同じエラーがでるようになりました。

$ zig version
0.11.0-dev.2868+1a455b2dd

@memsetの仕様変更

エラーに発生した箇所は@memsetを使っているところで、これの引数の数が3個から2個に変更になったようです。

言語仕様も更新されていました。
https://ziglang.org/documentation/master/#toc-memset

今までの@memsetはCの関数のmemsetと同等のものでしたが、仕様変更後は第一引数がポインタからスライスに変更になりました。第三引数で渡していた長さはスライスの長さとして渡すことになりました。

修正方法

zigのmasterのgitのログをいろいろ見て回って、以下のような修正でいけるとわかりました。

diff --git a/src/v4l2capture.zig b/src/v4l2capture.zig
index aaf3a6f..f30d4cf 100644
--- a/src/v4l2capture.zig
+++ b/src/v4l2capture.zig
@@ -96,14 +96,14 @@ pub const Capturer = struct {
 
     fn setDevice(self: *Self) !void {
         var fmt: c.struct_v4l2_format = undefined;
-        @memset(@ptrCast([*]u8, &fmt), 0, @sizeOf(c.struct_v4l2_format));
+        @memset(@ptrCast([*]u8, &fmt)[0..@sizeOf(c.struct_v4l2_format)], 0);
         fmt.type = c.V4L2_BUF_TYPE_VIDEO_CAPTURE;
         fmt.fmt.pix.width = self.width;
         fmt.fmt.pix.height = self.height;
         fmt.fmt.pix.pixelformat = self.pixelformat;
         fmt.fmt.pix.field = c.V4L2_FIELD_ANY;
         try self.xioctl(c.VIDIOC_S_FMT, @ptrToInt(&fmt));
-        @memset(@ptrCast([*]u8, &fmt), 0, @sizeOf(c.struct_v4l2_format));
+        @memset(@ptrCast([*]u8, &fmt)[0..@sizeOf(c.struct_v4l2_format)], 0);
         fmt.type = c.V4L2_BUF_TYPE_VIDEO_CAPTURE;
         try self.xioctl(c.VIDIOC_G_FMT, @ptrToInt(&fmt));
         if (fmt.fmt.pix.pixelformat != self.pixelformat) {

なお、同じタイミングで @memcpyの仕様も変わっています。

関連

https://zenn.dev/tetsu_koba/articles/7fb5e7d13479ba

Discussion