Skip to content

Returning pointer to a local const struct unexpectedly yields valid data #24209

Closed as not planned
@zpaceway

Description

@zpaceway

Zig Version

0.14.0

Steps to Reproduce and Observed Behavior

When you return a pointer to a local const-qualified struct, Zig does not allocate that binding on the stack by default. As a result, the pointer remains valid after the function returns—even though it wasn’t explicitly moved to the heap or marked comptime. This behavior feels surprising and can lead to subtle bugs when you expect a dangling pointer.

const std = @import("std");

const Foo = struct {
    bar: i64,
    data: [10]u8,
};

fn createFooVar() *Foo {
    var foo = Foo{
        .bar = 2,
        .data = [_]u8{0,1,2,3,4,5,6,7,8,9},
    };
    return &foo;
}

fn createFooConst() *const Foo {
    const foo = Foo{
        .bar = 2,
        .data = [_]u8{0,1,2,3,4,5,6,7,8,9},
    };
    return &foo;
}

pub fn main() !void {
    const fooVar = createFooVar();
    const fooConst = createFooConst();

    std.log.info("fooVar (corrupted)      = {any}", .{fooVar});
    std.log.info("fooConst (still intact) = {any}", .{fooConst});
}

output

info: fooVar (corrupted)      = conv.Foo{ .bar = 140734223737152, .data = { 185, 248, … } }
info: fooConst (still intact) = conv.Foo{ .bar = 2,               .data = {   0,   1, … } }

Expected Behavior

Both createFooVar and createFooConst should yield corrupted data or compile-time errors when returning a pointer to a local binding.

Alternatively, only a value explicitly marked comptime should live beyond the function scope.

This discrepancy violates the expectation that plain const implies a runtime stack allocation. It would be helpful to clarify whether this is intentional or an oversight in the compiler’s allocation strategy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionNo questions on the issue tracker, please.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions