Result location semantics with a buffer inside a labeled block

I found the following code in std/Thread.zig.

    const name_with_terminator = blk: {
        var name_buf: [max_name_len:0]u8 = undefined;
        @memcpy(name_buf[0..name.len], name);
        name_buf[name.len] = 0;
        break :blk name_buf[0..name.len :0];
    };

It’s returning a slice of a buffer defined inside a labeled block. I believe this is a form of Result Location Semantics. Could anyone elaborate on why this is valid?

1 Like

AFAIK it is not. RLS would be returning the whole buffer, not a slice.

Also worth noting that currently, you can reference local variables outside the scope they were defined. But the intended language semantics is the opposite. It is simply the compiler isn’t implemented correctly, and it isn’t a high enough priority to fix.

It is also possible Andrew is considering changing the intended semantics to align with the current compiler behaviour, though I haven’t heard anything about this.

Hm, I’ve heard that the intended language semantics is that local variables are live until the end of enclosing function/loop

This makes sense to me:

  • Extending the lifetime prevents bugs and simplifies the code.
  • The optimizer should be capable of precisely tracking what is actually used and what’s not. Even with C/C++ rules, there is going to be liveness analysis in the optimization pipeline, so it’s not like the surface language-level rule changes much in the resulting code.

This is actually one of the smaller happy consequences of abandoning RAII: with RAII, you are forced to language lawyer when exactly drop happens, with a tone of finicky rules (e.g. if let temporary scope - The Rust Edition Guide). With defer, you have very explicit syntax for where side-effects happen, and the stack memory can have “whatever” lifetime.

1 Like

That is the current behaviour.

Perhaps I am misremembering, it changed, or it was misinformation. But I did hear, I think from a team member, that the intended behaviour was for locals to live to the end of the scope.

1 Like

That is concerning, asked the grown ups at #compiler > Lifetime of locals @ :speech_balloon:

3 Likes

Good to get clarity on these things - a somewhat similar question popped up from time to time (can you safely return a pointer to local from inline functions?) and we got a definite answer: https://github.com/ziglang/zig/issues/25312#issuecomment-3324791040

3 Likes