Surprising side effect using print statements

Hey!

While trying to learn more about zigs internpool i stumbled upon this issue, which i can’t wrap my head around.

Simplified Code example:

    const key: Key = .{ .one = .{ .one = 1234, .two = "hello world" } };

    const seed = @backingInt(key);
    std.debug.print("{d}\n", .{seed});
    switch (key) {
        .one => |v| {
            const x: u64 = std.hash.Wyhash.hash(1, std.mem.asBytes(&v));
            std.debug.print("{d}\n", .{x});
        },
        else => {},
    }

    const z: u64 = 1;
    std.debug.print("{d}\n", .{z});
    std.debug.print("hello world\n", .{});

My observations:

  1. When running this code as is, the value of x is 8864718373389434152.
  2. When removing the print statements after the switch case x suddenly becomes 13165288763890694823.
  3. Additionally removing the seed print statement (note, seed was never even used for the hash) x prints as 5643058626213398210.

Now, i’m pretty surprised by this behaviour! I’d guess it’s a bug, but i’m also unfamiliar with wyhash, so i could as well be doing something wrong.

The Code in question i’ve looked at is the hash64 function of the internpool.
It happens on 0.16 and master in Debug mode. ReleaseSafe seems to be printing consistent results (although different ones all together) so i’m thinking it’s a bug with the self hosted backend.

If someone has any idea what’s going on let me know!

Thanks!

Is it that you’re hashing a structure that has a slice (i.e.ptr + len) in it, and the pointer is changing because the string is moving in memory?

1 Like

This seems to be it! Totally on the money :smiley:
Thanks!