Is it okay to expose local comptime-known const variables?

The following code shows it is not okay to expose local non-constant variables,
But is the bar function guaranteed to always return { 5, 6 }?

const std = @import("std");

fn foo() []u32 {
  var a = [_]u32{5, 6};
  return &a;
}

fn bar() []const u32 {
  const a = [_]u32{5, 6};
  return &a;
}

pub fn main() !void {
  var x = foo();
  std.debug.print("{any}\n", .{x}); // { 2, 6 }
  var y = bar();
  std.debug.print("{any}\n", .{y}); // { 5, 6 }
}
1 Like

This is similar to a question I posed a while ago: Do comptime variables have "static" lifetime?

The example that @kristoff gave could be modified to suite your needs here because it shows up as part of a type definition.

fn foo() [] u32 {
  const Internal = struct {
     var a = [_] u32 {5, 6};
  };
  return &Internal.a;
}

fn bar() [] const u32 {
  const Internal = struct {
     const a = [_] u32 {5, 6};
  };
  return &Internal.a;
}

pub fn main() !void {
    std.debug.print("\n{any}\n", .{ foo() });
    std.debug.print("\n{any}\n", .{ bar() });
}
2 Likes

I don’t actually know, but istm that this is equivalent to a similar question about this program:

fn hello() []const u8 {
    return “hello, world!”;
}

So hopefully the answer is yes!

1 Like

Yes, all comptime-known values have an infinite lifetime (at runtime) and are garbage collected by the compiler (at compile time).

5 Likes