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

Switch expression returns incorrect value. #8640

Open
neuring opened this issue Apr 29, 2021 · 7 comments
Open

Switch expression returns incorrect value. #8640

neuring opened this issue Apr 29, 2021 · 7 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@neuring
Copy link

neuring commented Apr 29, 2021

Hello, I encountered the following bug when trying to use switch expressions.

When running the code below, I would expect that the variable state to change to the value States.B after char changes to the value '.'.
Instead the value of state stays the same.

When examining the assembly it seems that the value is correctly changed at first, but shortly after replaced with the value of States.A
https://godbolt.org/z/d9aaTj6z8

const std = @import("std");

pub fn parse_number(input: []const u8) void {
    const States = enum { A, B};

    var current: usize = 0;

    var state = States.A;
    
    while (true) {
        const char = if (current < input.len)
            input[current]
        else
            break;

        std.debug.print("char = {c}, state before = {a}\n", .{ char, state });
        state = switch (state) {
            States.A => switch (char) {
                '0'...'9' => blk1: {
                    std.debug.print("AAAAAA\n", .{});
                    break :blk1 States.A;
                },
                '.' => blk2: {
                    std.debug.print("BBBBBB\n", .{});
                    break :blk2 States.B;
                },
                else => break,
            },
            States.B => break,
        };
        std.debug.print("state after = {a}\n", .{state});

        current += 1;
    }
}

pub fn main() void {
    parse_number("14.55");
}

Output

char = 1, state before = States.A
AAAAAA
state after = States.A
char = 4, state before = States.A
AAAAAA
state after = States.A
char = ., state before = States.A
BBBBBB
state after = States.A
char = 5, state before = States.A
AAAAAA
state after = States.A
char = 5, state before = States.A
AAAAAA
state after = States.A

I'm using zig version 0.8.0-dev.2008+6cd71931c.

@Vexu Vexu added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Apr 30, 2021
@Vexu Vexu added this to the 0.9.0 milestone Apr 30, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
@Sirius902
Copy link

Sirius902 commented Nov 28, 2021

I'm also having a similar problem where the result of a switch is different if the variable is const. Example:

const std = @import("std");

pub fn main() void {
    const x: u32 = 1;
    var y = x;

    std.log.info("{s}", .{switch (x) {
        0 => @as([]const u8, "a"),
        1 => @as([]const u8, "b"),
        2 => @as([]const u8, "c"),
        else => @as([]const u8, "wow"),
    }});

    std.log.info("{s}", .{switch (y) {
        0 => @as([]const u8, "a"),
        1 => @as([]const u8, "b"),
        2 => @as([]const u8, "c"),
        else => @as([]const u8, "wow"),
    }});
}

The above program prints

info: b
info: wow

instead of the expected

info: b
info: b

@ryoppippi
Copy link
Contributor

const std = @import("std");

pub fn main() void {
    var y: u32 = 1;
    var answer = switch (y) {
        1 => @as([]const u8, "b"),
        else => @as([]const u8, "wow"),
    };

    std.log.info("{d},{s}", .{ y, answer });
}

This works. So I think this may not be a problem of switch expression?

@ryoppippi
Copy link
Contributor

const std = @import("std");

pub fn main() void {
    var y: u32 = 1;

    std.log.info("{s}", .{switch (y) {
        1 => @as([]const u8, "b"),
        else => unreachable,
    }});
}

Also this works.

@nektro
Copy link
Contributor

nektro commented Aug 10, 2022

@Sirius902's case is a duplicate of #7097

@ryoppippi
Copy link
Contributor

idk I tested this behavior on the nightly build. so if this problem still exists, you can keep this issue.

@nektro
Copy link
Contributor

nektro commented Aug 10, 2022

unless the initial code snippet is also a duplicate, it needs to be added to https://github.com/ziglang/zig/tree/master/test/cases/ to catch/prevent regressions in order for the issue to be closed

@ryoppippi
Copy link
Contributor

ok so
@Sirius902's problem and @neuring's problem are different ones. I understand what you mean @nektro
Thanks

RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 9, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 9, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 9, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 9, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 9, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 10, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Sep 10, 2024
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Nov 24, 2024
alexrp pushed a commit to RetroDev256/zig that referenced this issue Feb 5, 2025
RetroDev256 added a commit to RetroDev256/zig that referenced this issue Feb 5, 2025
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 stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
6 participants