-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
access to packed struct fields returns incorrect value #10873
Comments
For some reason the offset is not taken into account, the returned value pub const database_settings = DatabaseSettings{
.name = [8]u8{ 0x7a, 0x65, 0x6e, 0x64, 0x79, 0x20, 0x20, 0x20 },
.version = .{ .major = 0xaaaa, .minor = 0xbbbb, .patch = 0xcccc },
};
// ...
var s = MetaBlock.createNoHash();
std.debug.print("offsetOf info: {}\n", .{@offsetOf(@TypeOf(s), "info")});
std.debug.print("offsetOf version: {}\n", .{@offsetOf(@TypeOf(s.info), "version")});
const memory = @ptrCast([*]u8, &s.info)[0..@sizeOf(@TypeOf(s.info))];
std.debug.print("hex [0x{}]\n", .{std.fmt.fmtSliceHexLower(memory)});
std.debug.print("ptr1 {p}\n", .{@ptrCast(*u8, &s.info)});
std.debug.print("ptr2 {p}\n", .{@ptrCast(*u8, &s.info.version)}); Gives:
Also, doing this at test "comptime the same thing" {
comptime {
try expect(database_settings.version.major == 0xaaaa);
var s = MetaBlock.createNoHash();
try expect(s.info.version.major == 0xaaaa);
}
} Passes the test. |
It doesn't work even without const std = @import("std");
const Allocator = std.mem.Allocator;
const expect = std.testing.expect;
pub const DatabaseVersion = packed struct {
major: u16,
minor: u16,
patch: u16,
};
pub const FileLayoutVersion = packed struct {
major: u16,
minor: u16,
patch: u16,
};
pub const DatabaseSettings = packed struct {
const Self = @This();
//name: [8]u8,
version: DatabaseVersion,
layout: FileLayoutVersion,
};
pub const database_settings = DatabaseSettings{
//.name = [8]u8{ 0x7a, 0x65, 0x6e, 0x64, 0x79, 0x20, 0x20, 0x20 },
.version = .{ .major = 0, .minor = 0, .patch = 1 },
.layout = .{ .major = 0, .minor = 0, .patch = 1 },
};
pub const MetaBlock = packed struct {
const Self = @This();
info: DatabaseSettings,
pub fn createNoHash() Self {
return Self{
.info = database_settings,
};
}
};
test "create default metadata block" {
try expect(database_settings.version.major == 0);
var s = MetaBlock.createNoHash();
std.debug.print("major: {}\n", .{s.info.version.major});
std.debug.print("offsetOf info: {}\n", .{@offsetOf(@TypeOf(s), "info")});
std.debug.print("offsetOf version: {}\n", .{@offsetOf(@TypeOf(s.info), "version")});
std.debug.print("offsetOf version.patch: {}\n", .{@offsetOf(@TypeOf(s.info.version), "patch")});
std.debug.print("version.patch: {}\n", .{s.info.version.patch});
try expect(s.info.version.major == 0);
try expect(s.info.version.minor == 0);
try expect(s.info.version.patch == 1);
} So, in general, I consider (at least nested) |
Lowering into LLVM IR is wrong, everything is safe-and-sound in AIR stage. Consider the following: pub fn accessStructField(meta: MetaBlock) u16 {
return meta.info.version.major + 1;
} While using
And for
In short, only one |
std.debug.print("hex [0x{}]\n", .{std.fmt.fmtSliceHexLower(memory)}); |
Is this the same as #11514 ? |
I have encountered a similar issue (on const Root = packed struct {
foo: Foo = .{},
bar: Bar = .{},
pub fn init() Root {
return .{};
}
};
const Foo = packed struct {
x: u8 = 0xAA,
y: u16 = 0xBBCC,
};
const Bar = packed struct {
z: u24 = 0xDDEEFF
};
const expectEqual = @import("std").testing.expectEqual;
test "comptime Root.init()" {
const root = comptime Root.init();
try expectEqual(@as(u8, 0xAA), root.foo.x);
try expectEqual(@as(u16, 0xBBCC), root.foo.y);
try expectEqual(@as(u24, 0xDDEEFF), root.bar.z);
}
test "Root.init().foo.x" {
try expectEqual(@as(u8, 0xAA), Root.init().foo.x);
}
test "Root.init().foo.y" {
try expectEqual(@as(u16, 0xBBCC), Root.init().foo.y);
}
test "Root.init().bar.z" {
try expectEqual(@as(u24, 0xDDEEFF), Root.init().bar.z);
} The 3 last tests fail:
|
Arrays are no longer allowed in packed structs. |
Zig Version
0.10.0-dev.358+36f13f591
Steps to Reproduce
Expected Behavior
Test should pass and
source_meta_block.info.version.major
return0
Actual Behavior
Returns
25978
The text was updated successfully, but these errors were encountered: