Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialization of array of pointers to u8 results in different values than array of u8 #19151

Closed
adworacz opened this issue Mar 2, 2024 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@adworacz
Copy link

adworacz commented Mar 2, 2024

Zig Version

0.12.0-dev.3123+147beec7d

Steps to Reproduce and Observed Behavior

The following test says it all. I did my best to search for previous bug reports on this, but I just couldn't find anything similar, so apologies if I missed something obvious somewhere.

If I try to produce an array of u8's, with values 1, 2, and 3, the following code works. But if I produce an array of pointers to u8's, then all of it's values are initialized to 3, instead of 1, 2, and 3.

Here's the code:

test "array initialization" {
    var foo: [3]u8 = undefined;
    for (0..3) |i| {
        const bar: u8 = @intCast(i + 1);
        foo[i] = bar;
    }
    // passes
    try std.testing.expectEqual(1, foo[0]);

    var src: [3]*u8 = undefined;
    for (0..3) |i| {
        var bar: u8 = @intCast(i + 1);
        src[i] = &bar;
    }
    // fails, "expected 1, found 3"
    try std.testing.expectEqual(1, src[0].*);
}

Resulting error:

error: 'main.test.array initialization' failed: expected 1, found 3
/home/user/.zvm/master/lib/std/testing.zig:93:17: 0x103bec8 in expectEqualInner__anon_2083 (test)
                return error.TestExpectedEqual;
                ^
/tmp/zig-test/src/main.zig:77:5: 0x103c22e in test.array initialization (test)
    try std.testing.expectEqual(1, src[0].*);
    ^
error: while executing test 'main.test.array initialization', the following test command failed:

This was tested using zig build test --summary all in a fresh zig init project.

Expected Behavior

Array initialization should work reliably for pointers, just like it does for non-pointers.

@adworacz adworacz added the bug Observed behavior contradicts documented or intended behavior label Mar 2, 2024
@adworacz adworacz changed the title Initialization of array of pointers results in different values than u8 Initialization of array of pointers to u8 results in different values than array of u8 Mar 2, 2024
@mlugg
Copy link
Member

mlugg commented Mar 2, 2024

The pointers you store into src point to a local variable (bar) which goes out of scope on each loop iteration. This invalidates the value, since the lifetime of runtime-known local variables is tied to their scope. (In practice, what's happening here is that the same stack memory is reused for bar each iteration.)

I would give specific advice if I could, but I don't know enough about your use case to do so. If you'd like help here, I'd encourage you to join a Zig community.

@mlugg mlugg closed this as not planned Won't fix, can't repro, duplicate, stale Mar 2, 2024
@adworacz
Copy link
Author

adworacz commented Mar 2, 2024

Okay, thank you for your help.

I think this behavior is still very surprising, particularly given Zig's argument for "no hidden behavior". Looking at the code above, I wouldn't have been able to tell that the same stack memory is going to be reused for the entire array.

Considering that the scope is lost, I'd almost expect for the compiler to complain somehow.

Regardless, I'll reach out to the Zig communities you posted as well.

However, I suspect I'm not the only developer to be stung by this surprising behavior.

@schmee
Copy link
Contributor

schmee commented Mar 2, 2024

The general problem of detecting use after free of local stack variables is tracked in #3180.

@adworacz
Copy link
Author

adworacz commented Mar 4, 2024

Ahh, thank you @schmee. I'll be sure to follow that issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants