Packed struct bug.
Zig Version
0.14.0-dev.839+a931bfada
Steps to Reproduce and Observed Behavior
const std = @import("std");
pub const Foo = packed struct {
a: u31,
b: bool,
pub fn init() Foo {
return .{ .a = undefined, .b = true };
}
};
pub fn foo(a: Foo) void {
std.debug.print("{} {b}\n", .{a.b, @as(u32, @bitCast(a))});
// Expected "true", and a non zero value
// Found "false", 0
}
pub fn main() !void {
const a = Foo.init();
foo(a);
}
Expected Behavior
There seems to be an issue with passing a packed struct into a function when the first field is initialized as undefined.
I am able to reproduce this on windows without the foo function:
const std = @import("std");
pub const Foo = packed struct {
a: u31,
b: bool,
pub fn init() Foo {
return .{ .a = undefined, .b = true };
}
};
pub fn main() !void {
const a = Foo.init();
std.debug.print("{} {b}\n", .{a.b, @as(u32, @bitCast(a))});
// Expected "true", and a non zero value
// Found "false", 0
}
$ zig run foo.zig
true 10111000111110011110110010010000
$ zig run foo.zig
false 10111010011011010010010110000
Duplicate of #20095
@Vexu I don't believe this is a duplicate. #20095 is about reading undefined fields, but we are reading a field that has been set to true and seeing undefined behavior.
I believe this issue is only in the llvm backend:
const exe = b.addExecutable(.{
.name = "foo2",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.use_llvm = false,
});
true 10000000000000000000000000000000
true 10000000000000000000000000000000
true 10000000000000000000000000000000
true 10000000000000000000000000000000
I'd expect it to be caused by the same issue but we can keep this open too.
I'm observing something similar (the same?) with this minimal repro on 0.13.0
const std = @import("std");
const Bar = packed struct {
magic: u32 = undefined, // When this moves, assert goes away
supposed_to_be_one: u32 = 1,
};
const Foo = struct {
pack: Bar = .{},
};
fn create_foo() Foo {
return .{};
}
pub fn main() !void {
const works: Foo = .{};
std.debug.assert(works.pack.supposed_to_be_one == 1);
const fails = create_foo();
std.debug.assert(fails.pack.supposed_to_be_one == 1);
}
Note that this problem is fixed for me with 0.14.0-dev.2627+6a21d18ad
Steps to Reproduce and Observed Behavior
incomplete
Expected Behavior
incomplete
the zig team is perfectly capable of finding and fixing bugs ourselves. if you file an issue you're basically asking for priority service. if you want priority service then please fill out the damn form.
I think your GitHub page may be having problems because the reproduction steps and expected behavior are in https://github.com/ziglang/zig/issues/20938#issue-2447158131.
Aside from that, I reran the original reproduction and the issue seems to have been fixed at some point as Ryp mentioned.
// foo.zig
const std = @import("std");
pub const Foo = packed struct {
a: u31,
b: bool,
pub fn init() Foo {
return .{ .a = undefined, .b = true };
}
};
pub fn main() !void {
const a = Foo.init();
std.debug.print("{} {b}\n", .{ a.b, @as(u32, @bitCast(a)) });
// Expected "true", and a non zero value
// Found "false", 0
}
$ zig run foo.zig
true 10000000000000000000000000000000
$ zig version
0.14.0-dev.2627+6a21d18ad
I think your GitHub page may be having problems
although farfetched it is very charitable, thank you for that gesture.
I see these comments upon closer examination:
// Expected "true", and a non zero value
// Found "false", 0
so this was a case of triaging too fast. sometimes when something is a little bit sloppy (it didn't pedantically fill out the form) but technically ok, it can easily be misidentified as yet another crappy issue report in a sea of crappy issue reports.
I apologize but I'm also going to reserve the right to close issues that don't pedantically fill out the template