return type '?*const fn () callconv(.C) void' cannot cast into return type '?*anyopaque'
Zig Version
0.12.0-dev.1828+225fe6ddb
Steps to Reproduce and Observed Behavior
I am trying to link GLFW and GLAD. related headers in GLAD:
typedef void* (* GLADloadproc)(const char *name);
int gladLoadGLLoader(GLADloadproc);
This is my wished C code:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
My current zig code:
const c_cast = @import("std").zig.c_translation.cast;
if (c.gladLoadGLLoader(c_cast(c.GLADloadproc, c.glfwGetProcAddress)) == c.GL_FALSE)
This is the understanding from zls:
pub const GLADloadproc = ?*const fn ([*c]const u8) callconv(.C) ?*anyopaque;
pub extern fn gladLoadGLLoader(GLADloadproc) c_int;
pub const GLFWglproc = ?*const fn () callconv(.C) void;
pub extern fn glfwGetProcAddress(procname: [*c]const u8) GLFWglproc;
This is the error:
[zig]\lib\std\zig\c_translation.zig:98:26: error: expected type '*const fn ([*c]const u8) callconv(.C) ?*anyopaque', found '*const fn ([*c]const u8) callconv(.C) ?*const fn () callconv(.C) void'
return @as(DestType, target);
^~~~~~
[zig]\lib\std\zig\c_translation.zig:98:26: note: pointer type child 'fn ([*c]const u8) callconv(.C) ?*const fn () callconv(.C) void' cannot cast into pointer type child 'fn ([*c]const u8) callconv(.C) ?*anyopaque'
[zig]\lib\std\zig\c_translation.zig:98:26: note: return type '?*const fn () callconv(.C) void' cannot cast into return type '?*anyopaque'
[zig]\lib\std\zig\c_translation.zig:98:26: note: cast discards const qualifier
Expected Behavior
it working
Yes but it works in C: https://learnopengl.com/Getting-started/Hello-Window
This looks like an oversight in c_cast where function bodies (fn () void) are not coerced to function pointers (*const fn () void).
In the meantime, you can fix the issue by either adding a & before the function name to explicitly take a pointer to it
const c_cast = @import("std").zig.c_translation.cast;
-if (c.gladLoadGLLoader(c_cast(c.GLADloadproc, c.glfwGetProcAddress)) == c.GL_FALSE)
+if (c.gladLoadGLLoader(c_cast(c.GLADloadproc, &c.glfwGetProcAddress)) == c.GL_FALSE)
or by using @ptrCast
const c_cast = @import("std").zig.c_translation.cast;
-if (c.gladLoadGLLoader(c_cast(c.GLADloadproc, c.glfwGetProcAddress)) == c.GL_FALSE)
+if (c.gladLoadGLLoader(@ptrCast(&c.glfwGetProcAddress)) == c.GL_FALSE)
@ptrCast is probably the way to go if you're writing original code in Zig. Functions in c_translation are mainly meant for automatically translated code.
thanks :)