Zig: question about copy elision

Created on 9 Oct 2019  Â·  5Comments  Â·  Source: ziglang/zig

Hey guys,

I have a question about the newly introduced copy elision. Is the compiler able to determine that it should immediately write into first_set.data in the unionize function?

const std = @import("std");

fn getByte(n: usize) usize {
    return n >> 3;
}

fn getBitOffset(n: usize) u3 {
    return @intCast(u3, n & 7);
}

fn setBit(bytes: var, bit: usize) void {
    const offset = getByte(bit);
    const idx = getBitOffset(bit);

    bytes[offset] |= (u8(1) << idx);
}

pub fn Set(comptime capacity: usize) type {
    const data_size = capacity / 8;

    return struct {
        const Self = @This();

        data: [data_size]u8,

        pub fn init() Self {
            return Self{ .data = [_]u8{0} ** data_size };
        }

        pub fn add(self: *Self, bit: usize) void {
            setBit(&self.data, bit);
        }

        pub fn unionize(a: Self, b: Self) Self {
            var result: Self = Self.init();
            var i: usize = 0;

            while (i < data_size) : (i += 1) {
                // Is this effectively equal to `a` being of type `*Self` and doing
                //     a.data[i] |= b.data[i];

                result.data[i] = a.data[i] | b.data[i];
            }

            return result;
        }
    };
}

pub fn main() anyerror!void {
    const MySet = Set(100);

    var first_set = MySet.init();
    var second_set = MySet.init();

    second_set.add(10);

    first_set = first_set.unionize(second_set);
}

Edit: I'm sorry if this seems like a code-dump, but I wanted to provide a running example :)

question

All 5 comments

This is #2765.

Awesome, thank you very much :)

Related question: Do you advise against designing an API around this feature? Would it be more reliable to have my function still take a pointer to *Self, because the elision can be fooled in some cases?

Bump – You upvoted my comment just before I made the edit, which makes me think you're never going to see it otherwise. I'm sorry if that's not the case ^^

If the semantics of your application depend on elision, you can't write the code this way, you'll have to take a pointer. But I fully intend on making #2765 a reality, which means that when the issue is implemented, you could then improve your API to not need to take a pointer anymore. There are a bunch of places in the std lib that are affected in this way.

Oh... didn't notice the issue is still open. I'll wait it out then.

Thanks for your (and every other contributors) work by the way. I never really used Zig for something productive, but it got me into low-level programming and is amazingly fun to work with :)

Was this page helpful?
0 / 5 - 0 ratings