ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.24k stars 2.5k forks source link

implement `@memcpy` and `@memset` for tuples #15479

Open andrewrk opened 1 year ago

andrewrk commented 1 year ago

Extracted from #15278.

This test should pass:

const std = @import("std");
const expect = std.testing.expect;

test "memset a tuple" {
    var t: struct { i32, i32 } = .{ 12, 34 };
    @memset(&t, [_]i32{ 56, 78 });
    try expect(t[0] == 56);
    try expect(t[1] == 78);
}

test "memcpy a tuple" {
    var t1: struct { i32, i32 } = .{ 12, 34 };
    var t2: struct { i32, i32 } = .{ 56, 78 };
    @memset(&t1, &t2);
    try expect(t1[0] == 56);
    try expect(t1[1] == 78);
}

Instead, this happens:

$ stage4/bin/zig test test.zig 
test.zig:6:13: error: type '*test.test.memset a tuple__struct_1040' does not support indexing
    @memset(&t, [_]i32{ 56, 78 });
            ^~
test.zig:6:13: note: for loop operand must be an array, slice, tuple, or vector
test.zig:14:13: error: type '*test.test.memcpy a tuple__struct_1041' does not support indexing
    @memset(&t1, &t2);
            ^~~
test.zig:14:13: note: for loop operand must be an array, slice, tuple, or vector
InKryption commented 1 year ago

What's the use case behind this? Why would one opt for the builtins when we can already do foo = bar and foo = .{ 12, 14 }, bar = .{0} ** bar.len?

andrewrk commented 1 year ago

Same as the reason that @memcpy supports both src and dest being an array, even though it is equivalent to dest.* = src.*. The reason being language consistency.

mlugg commented 1 year ago

To implement this reasonably, as well as for more general consistency between arrays and tuples, Zig should define homogeneous tuples (by which I mean tuples whose fields all have the same type) as having the same memory layout as arrays (i.e. fields laid out contiguously in memory with no extra padding). Is this something which the (theoretical) spec already guarantees? (As far as I know the implementation does, although I haven't checked.)