Skip to content

translate-c: cast function pointer to void pointer #24513

@paokitore

Description

@paokitore

Zig Version

0.14.1

Steps to Reproduce and Observed Behavior

C code that casts a function pointer to a non const data pointer (void* for example) translates incorrectly.

This issue is specific to function pointers as casting const T* to T* correctly translates to @as(?*anyopaque, @ptrCast(@volatileCast(@constCast(ptr)))).

I know that casting function pointers to data pointers can be undefined behavior but a lot of compilers (clang) allow it.

When trying to translate c code (which compiles fine with clang version 20.1.8):

int fn(int a) {
  return 2*a;
}
void main() {
  int (*f)(int) = fn;
  void *g = (void*)f;
  int (*h)(int) = (int (*)(int))g;

  h(3);
}

zig translate-c test.c outputs:

// ...
pub export fn @"fn"(arg_a: c_int) c_int {
    var a = arg_a;
    _ = &a;
    return @as(c_int, 2) * a;
}
pub export fn main() void {
    var f: ?*const fn (c_int) callconv(.c) c_int = &@"fn";
    _ = &f;
    var g: ?*anyopaque = @as(?*anyopaque, @ptrCast(f));
    _ = &g;
    var h: ?*const fn (c_int) callconv(.c) c_int = @as(?*const fn (c_int) callconv(.c) c_int, @ptrCast(@alignCast(g)));
    _ = &h;
    _ = h.?(@as(c_int, 3));
}
// ...

And compiling that outputs error:

test.zig:65:43: error: @ptrCast discards const qualifier
    var g: ?*anyopaque = @as(?*anyopaque, @ptrCast(f));
                                          ^~~~~~~~~~~

Expected Behavior

It should probably use @constCast

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviortranslate-cC to Zig source translation feature (@cImport)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions