Is it safe to return an optional stack value?

I can’t quite tell from the docs if this is safe:

const Foo = struct { a: i32 };
fn returnsOptionalStruct() ?Foo {
    return .{ .a = 3 };
}

This has a similar energy as returning a pointer to a local stack value. Certainly it wouldn’t be ok if the function return type was ?*Foo. But I’m unsure about optional values.

(AFAIK) Optionals in that case would use a tagged union under the hood. Returning a tagged union is fine.

1 Like

I’m returning optional struct values in my code and they seem to work just fine. But as I didn’t know how they actually work, I was worried that it’s some kind of a pointer to a stack value.

If it’s a tagged union (and it makes sense that it would be), then this should work just fine! Thanks for the reply!

No problem. I’m not a Zig developer but the way I think of it is that optional pointers ?* and optional values ? are distinct concepts but related and share some of the syntax.

The only thing that can cause trouble are pointers, as they’re the one mechanism that lets you refer to data placed somewhere else. This applies to both returning a pointer directly (as mentioned by OP) or a struct/union that contains a pointer to itself / other data that lives in the function’s frame, kinda like this, for example:

const Foo = struct {
   num_ptr: *const usize,
};

fn bad() Foo {
   const a: usize = 6;
   return Foo { .num_ptr = &a};
}

fn good(allocator: std.mem.Allocator) Foo {
  const a_ptr = allocator.create(usize);
  return Foo { .num_ptr = a_ptr };
}

// The following is bad because fn argument values are copied
// into the function's frame stack.
fn bad2(a: usize) Foo {
   return Foo { .num_ptr = &a};
}

fn good2(a_ptr: *const usize) Foo {
   return Foo { .num_ptr = a_ptr};
}

I’m not sure I understand the point you’re making. We do have an issue to eventually catch simple situations where you’re returing a pointer to a local variable, and make that an error.

Oh, nothing special, do not pay very much attention to it, I’ve just remembered I posted something about returning local vars pointer. Sorry If that confused you… It was not a complain about ZIg.

That’s great, could you please give a link to that issue (unfortunately I could not find it myself)?

No worries, I was actually trying to understand what you meant with the link. Here’s a link to that issue.

https://github.com/ziglang/zig/issues/2646

Ok. :slight_smile: I wanted to say - “Yes, returning a pointer to a stack variable is a bug (in any language)”, so it was just a sort of an echo to these your words - “The only thing that can cause trouble are pointers”.

Thanks for the link! It seems it is rather old issue.