Skip to content

Immutable struct changed in function call #11596

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

Closed
miquille opened this issue May 6, 2022 · 1 comment
Closed

Immutable struct changed in function call #11596

miquille opened this issue May 6, 2022 · 1 comment
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@miquille
Copy link

miquille commented May 6, 2022

Zig Version

0.9.1

Steps to Reproduce

const std = @import("std");

const Pair = struct {
    x: i32,
    y: i32,

    pub fn flip(t: Pair) Pair {
        return Pair{.y = t.x, .x = t.y};
    }
};

test "it should swap the values" {
    var v = Pair{.x = 10, .y = 4};
    v = v.flip();
    try std.testing.expectEqual(v.y, 10);
    try std.testing.expectEqual(v.x, 4); //Fails, it's 10 now
}

test "what actually happens" {
    var v = Pair{.x = 10, .y = 4};
    v = v.flip();
    try std.testing.expectEqual(v.x, 10);
    try std.testing.expectEqual(v.y, 10);
}

OS: Mac OS 12.3.1 (21E258), arm64

Note: Adding a temporary value resolves the problem, eg:

    pub fn flip(t: Pair) Pair {
        const tmp = Pair{.y = t.x, .x = t.y};
        return tmp;
    }

Expected Behavior

Either the behavior indicated by the test (eg: a new struct to be created with the values swapped (eg {.x = 4, .y = 10} after v.flip() and for that value to be assigned to v replacing it.)

test "it should swap the values" {
    var v = Pair{.x = 10, .y = 4};
    v = v.flip();
    try std.testing.expectEqual(v.y, 10);
    try std.testing.expectEqual(v.x, 4); //Fails, it's 10 now
}

OR

A warning or compile error suggesting that assigning to a return value that is a modification of this can be optimized in undefined ways.

Actual Behavior

The value of x is set to 10 because it assigned first, then y is set to the new value of x (10) instead of the value that is being passed in via the struct (4).

test "what actually happens" {
    var v = Pair{.x = 10, .y = 4};
    v = v.flip();
    try std.testing.expectEqual(v.x, 10);
    try std.testing.expectEqual(v.y, 10);
}
@miquille miquille added the bug Observed behavior contradicts documented or intended behavior label May 6, 2022
@rohlem
Copy link
Contributor

rohlem commented May 6, 2022

This is a manifestation of #3696 (-> duplicate for the purpose of bug tracking, though I totally agree that it's an issue).

@Vexu Vexu closed this as completed May 6, 2022
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