Yesterday I tried playing with optionals, slices, etc., and ran into a strange thing I can’t explain.
Consider these two short examples:
Example 1:
const std = @import("std");
pub fn main() void
{
std.debug.print("{x:2>0}\n", .{ 0xFE });
std.debug.print("{x}\n", .{ 0xAB });
}
Works as expected -
zig run x_fmt.zig
fe
ab
Example 2:
const std = @import("std");
pub fn main() void
{
var a: ?[]const u8 = null;
if (a) |a_val|
{
std.debug.print("a is not null = {x:8>0}\n", .{ a_val });
}
}
Does not compile -
zig run x_fmt_deprecated.zig
/home/archie/apps/zig/lib/std/fmt.zig:976:16: error: specifier 'x' has been deprecated, wrap your argument in std.fmt.fmtSliceHexLower instead
'x' => @compileError("specifier 'x' has been deprecated, wrap your argument in std.fmt.fmtSliceHexLower instead"),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/archie/apps/zig/lib/std/fmt.zig:655:50: note: called from here
comptime checkTextFmt(actual_fmt);
~~~~~~~~~~~~^~~~~~~~~~~~
referenced by:
format__anon_7150: /home/archie/apps/zig/lib/std/fmt.zig:184:23
print__anon_4079: /home/archie/apps/zig/lib/std/io/writer.zig:28:34
remaining reference traces hidden; use '-freference-trace' to see all reference traces
Replacing
std.debug.print("a is not null = {x:8>0}\n", .{ a_val });
with
std.debug.print("a is not null = {s}\n", .{ std.fmt.fmtSliceHexLower(a_val) });
makes it compile, but doesn’t answer the question: how come example 1 works, and example 2 does not?
Is x
/ X
format deprecated, on its way out, or is it gone already? If yes, how do I apply additional parameters, like fill, alignment, width, etc.?
Also, example 2 compiles with this std.debug.print
statement:
std.debug.print("a is not null = {x:8>0}\n", .{ @intFromPtr(a_val.ptr) });