std.fmt.formatType fails when a field is a function
Zig Version
0.11.0-dev.1969+d525ecb52
Steps to Reproduce and Observed Behavior
const std = @import("std");
const ExampleStruct = struct {
method: fn () void,
};
fn method_impl() void {
}
pub fn main() void {
const s = ExampleStruct {
.method = method_impl,
};
std.debug.print("{}\n", .{ s });
}
Try using this example to print the structure. I believe the expected functionality should be similar to C which is to print the memory address of the method. Instead we get this error:
/nix/store/b9gg248ddpqp5pv26xmz937v2b6vwkc9-zig-0.11.0-dev.1969+d525ecb52/lib/std/fmt.zig:708:73: error: expected pointer, found 'fn() void'
return format(writer, "{s}@{x}", .{ @typeName(T), @ptrToInt(value) });
^~~~~
referenced by:
formatType__anon_6727: /nix/store/b9gg248ddpqp5pv26xmz937v2b6vwkc9-zig-0.11.0-dev.1969+d525ecb52/lib/std/fmt.zig:596:21
format__anon_6715: /nix/store/b9gg248ddpqp5pv26xmz937v2b6vwkc9-zig-0.11.0-dev.1969+d525ecb52/lib/std/fmt.zig:184:13
remaining reference traces hidden; use '-freference-trace' to see all reference traces
Expected Behavior
Zig should either print the memory address or name of the method instead of failing to compile.
fn () void is a function body type, not a function pointer. It doesn't exist at runtime so it doesn't have an address and the formatting code doesn't have access to the name of the function.
Why does *const fn () void work but not fn () void? I though all functions have an address or else they couldn't be executed by the CPU?
Because *const fn() void is a function pointer so it can also exist at runtime.
Now I'm confused, how does adding *const change the function in a way that makes the address accessible? As far as I know, you cannot execute code unless it is mapped into memory. That means it would have an address, so no matter if it's got *const or not, it exists in memory.
fn () void is a function body type, it does not exist at runtime. *const fn () void is a function pointer which has an address at runtime.
Well, that explains it a bit more but my methods are called at runtime and not at comptime. Adding *const did fix the issue but it also required a few other things in this to make it so it wouldn't error out on saying some structs depend on each other:
- https://github.com/ExpidusOS/neutron/commit/dd6b4fe71ac5bf6570521a92485b39a751e5a79d
- https://github.com/ExpidusOS/neutron/commit/33f58941078f7f5f72153e2f070200b33e461b3a
- https://github.com/ExpidusOS/neutron/commit/3a244cd8b51e885c94e629de75dcf074d2c8fc75
I've figured out how to fix it in my code, maybe it should throw an error differently there like:
Expected constant pointer function, got a function body type.