Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

non callconv(.C) function pointers no longer allowed in extern contexts #19921

Open
xdBronch opened this issue May 9, 2024 · 6 comments
Open
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@xdBronch
Copy link
Contributor

xdBronch commented May 9, 2024

Zig Version

0.12

Steps to Reproduce and Observed Behavior

const T = extern struct {
    f: *const fn () void,
};

export fn f(_: *const fn () void) void {}

comptime {
    _ = @as(T, undefined);
}
d.zig:5:13: error: parameter of type '*const fn () void' not allowed in function with calling convention 'C'
export fn f(_: *const fn () void) void {}
            ^~~~~~~~~~~~~~~~~~~~
d.zig:5:13: note: extern function must specify calling convention
d.zig:2:8: error: extern structs cannot contain fields of type '*const fn () void'
    f: *const fn () void,
       ^~~~~~~~~~~~~~~~~
d.zig:2:8: note: extern function must specify calling convention

this worked in 0.11, caused by #17509 see #17468 (comment)

Expected Behavior

no error

@xdBronch xdBronch added the bug Observed behavior contradicts documented or intended behavior label May 9, 2024
@Pyrolistical
Copy link
Contributor

Pyrolistical commented May 10, 2024

But without a callconv for extern fn you run into #19841.

What is the use case for unspecified callconv for extern fns?

@xdBronch
Copy link
Contributor Author

its not an unspecified callconv for extern fns, its a pointer to an unspecified callconv fn being passed to a callconv(.C) function. it would be seen as an opaque pointer on the C side

@Pyrolistical
Copy link
Contributor

Pyrolistical commented May 10, 2024

On the line export fn f(_: *const fn () void) void {}, fn f does not have a callconv, so it is unspecified. The function pointer param is not the issue.

For,

const T = extern struct {
    f: *const fn () void,
};

The function pointer needs a callconv or else how would zig know what to do when you write:

const t: T = ...
t.f();

If f wasn't callable and just an *anyopaque, you are free to cast it and cause unspecified behavior.

@xdBronch
Copy link
Contributor Author

xdBronch commented May 10, 2024

On the line export fn f(_: *const fn () void) void {}, fn f does not have a callconv, so it is unspecified. The function pointer param is not the issue.

the export implies the C calling convention, it is not unspecified. you arent allowed to export unspecified functions like that

comptime {
    @compileLog(@typeInfo(@TypeOf(exported)).Fn.calling_convention);
    @compileLog(@typeInfo(@TypeOf(not_exported)).Fn.calling_convention);
}

export fn exported() void {}
fn not_exported() void {}
Compile Log Output:
@as(builtin.CallingConvention, .C)
@as(builtin.CallingConvention, .Unspecified)

The function pointer needs a callconv or else how would zig know what to do when you write:

no callconv means zigs callconv (or other depending on context, zig knows because zig sees and is in control of the code), the point is to be callable on the zig side but opaque on the C side

@Pyrolistical
Copy link
Contributor

no callconv means zigs callconv (or other depending on context, zig knows because zig sees and is in control of the code), the point is to be callable on the zig side but opaque on the C side

AFAIK there is no such thing as a zig callconv for extern fn. If there were we could have extern fns with ErrorUnions

@xdBronch
Copy link
Contributor Author

thats exactly what im saying, there isnt

@Vexu Vexu added the frontend Tokenization, parsing, AstGen, Sema, and Liveness. label May 10, 2024
@Vexu Vexu added this to the 0.13.0 milestone May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

No branches or pull requests

3 participants