ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.7k stars 2.53k forks source link

broken packed struct initialization #21235

Closed Traxar closed 1 month ago

Traxar commented 2 months ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

const std = @import("std");
const expect = std.testing.expect;

const SliceAtHome = packed struct {
    const Slice = @This();
    ptr: [*]bool = undefined,
    len: usize = 0,

    pub inline fn init(n: usize) !Slice {
        var slice = Slice{ .len = n };
        slice = slice;
        return slice;
    }
};

test "MultiSlice" {
    const ms = try SliceAtHome.init(10);
    try expect(ms.len == 0); // passes
    try expect(ms.len == 10); // fails
}

Expected Behavior

test passes

ianprime0509 commented 2 months ago

Here's a related example:

const std = @import("std");

const S = packed struct {
    a: usize = undefined,
    b: usize,
};

pub fn main() void {
    const s_const: S = .{ .b = 123 };
    std.debug.print("{}\n", .{s_const.b});

    var s_var: S = .{ .b = 123 };
    _ = &s_var;
    std.debug.print("{}\n", .{s_var.b});
}

As of 0.14.0-dev.1349+6a21875dd, this prints

123
17007316

(at least for me; the second value will not necessarily be consistent since it appears to be uninitialized memory: https://godbolt.org/z/PM85achM7)

This example works as expected (prints 123 twice) if any of the following changes are made:

  1. Make S a regular (non-packed) struct
  2. Reorder the field b before a
  3. Choose any other default value for a besides undefined

May be related to #20095 and #20938 (both of which involve undefined being handled incorrectly in packed structs, but with different outcomes)

Traxar commented 2 months ago
  1. The example also works with the following replacement:
    // var s_var: S = .{ .b = 123 };
    var s_var: S = undefined;
    s_var.b = 123;

    This does not change anything about the behaviour elsewhere, compared to the other workarounds

Vexu commented 1 month ago

Duplicate of #20938