I'm debugging an issue where code that worked fine with zig v0.10.x breaks (badly) with zig v0.11.0 and I can't see why:
const packet = [_]u8{
0x17, 0x20, 0x00, 0x00, 0x78, 0x37, 0x2a, 0x18, 0x4e, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x01,
....
};
const offset = 20;
const bcd: []const u8 = try bcd2string(packet[offset..][0..7]);
const expected: []const u8 = "20220823094706";
std.debug.print(">>> BCD: {any}\n", .{ bcd });
std.debug.print(">>> expected: {any}\n", .{ expected });
std.debug.print(">>> eql(before): {any}\n", .{ std.mem.eql(u8, expected,bcd) });
if (std.mem.indexOfDiff(u8, bcd, expected)) |index| {
std.debug.print(">>> indexOfDiff: {any} {any} {any}\n", .{ expected, bcd, index });
}
std.debug.print(">>> eql(after): {any}\n", .{ std.mem.eql(u8, expected,bcd) });
fn bcd2string(slice: []const u8) ![]const u8 {
var buffer: [64:0]u8 = undefined;
return try std.fmt.bufPrint(&buffer, "{s}", .{ std.fmt.fmtSliceHexLower(slice)});
}
The output looks like:
>>> BCD: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 }
>>> expected: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 }
>>> eql(before): true
>>> indexOfDiff: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 } { 136, 252, 94, 228, 254, 127, 0, 0, 136, 252, 94, 228, 254, 127 } 0
>>> eql(after): false
It looks very much std.mem.indexOfDiff
is corrupting the slices which would be .. unexpected.
There's nothing obvious as to why in the Zig source or documentation - is there something just plain wrong with the code?
As I mentioned in the comments. Your bcd2string
function returns a slice that points to the stack memory of the bcd2string
function itself. The slice becomes invalid as soon as the function exits.
There are several ways to fix this:
bcd2string
.bcd2string
and let it allocate the result. But you'll have to make sure to free it afterwards.bcd2string
. This seems to make the most sense for the given code.