What is the current status of return value copy elision?

AFAIK we had this merged PR: result location mechanism (part of no-copy semantics) by andrewrk · Pull Request #2602 · ziglang/zig · GitHub

But when I experimented with this:

fn initSomething() !Something {
    var ret: Something = undefined;
    printAddress(&ref);
}

var a = initSomething();
printAddress(&a);

I see different addresses.

What am I missing?

Well first of all this line here:

var a = initSomething();

This line create a copy of the result location, because the result location is readonly and therefor cannot be stored in a var(see also why is the machine code different for these two different function calls? · Issue #16368 · ziglang/zig · GitHub). Note that this is trivial for llvm to optimize and should only be visible in debug.
If you did

const a = initSomething();

then the result location would actually be stored directly in a.

And secondly I think the result location is only used for the return statement and not forwarded to the variable that gets returned. So I think you’ll only observe it when you do something like this:

return .{...};

But then you cannot print the address of this. So you are trying to observe something that doesn’t want to be observed. I think you’d need to check the generated air or llvm-ir or assembly code.

Oh and also recently there was a change that limited the scope of RLS, disabling it for initializers with explicit type T{...}: Proposal: do not perform RLS on explicitly typed struct and array inits · Issue #17194 · ziglang/zig · GitHub

2 Likes

@IntegratedQuantum haha. Sounds like quantoms! If you don’t observe it then it’s uncertain!

I think the best practice for now is to forget about copy value elision until Zig reaches 1.0

3 Likes