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

Improve Syntax: extern "lib" is kinda out-of-language #20006

Open
ikskuh opened this issue May 19, 2024 · 2 comments
Open

Improve Syntax: extern "lib" is kinda out-of-language #20006

ikskuh opened this issue May 19, 2024 · 2 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@ikskuh
Copy link
Contributor

ikskuh commented May 19, 2024

Extracted from #19999:

Replace extern "libname" fn func () T with extern fn func() linklibrary("libname") T, the extern "libname" always felt out-of-language

Right now, we have a lot of linking or compilation modifiers as postfixes, except for the library the linker will search in. This library is an optional string-literal parameter to the extern keyword/modifier:

pub extern "SDL2" fn SDL_CreateWindow(…) ?*SDL_Window;

This kinda feels clunky and doesn't really fit everything else, especially considering that linksection() already is on the right, but also align(), which does modify the symbol linkage as well, and, if accepted, also linkname:

pub extern "SDL2" fn CreateWindow(…) linksection(".text") linkname("SDL_CreateWindow") align(4)  ?*SDL_Window;

If we now move the linked library also to the right, we gain consistency and remove a weird syntactical property:

pub extern fn CreateWindow(…) linklibrary("SDL2") linksection(".text") linkname("SDL_CreateWindow") align(4)  ?*SDL_Window;

Another benefit is that we prevent confusion with the omnipresent extern "C" from C++

@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label May 19, 2024
@Vexu Vexu added this to the 0.13.0 milestone May 19, 2024
@zzyxyzz
Copy link
Contributor

zzyxyzz commented May 21, 2024

All of these properties could also be parameters of extern. A bit messier, but all logically in one place and with three fewer keywords:

pub extern(.{ .lib = "SDL2", .name = "SDL_CreateWindow", .section = ".text" })
fn CreateWindow(title: [*:0]const u8, x: c_int, y: c_int, w: c_int, h: c_int, flags: u32) align(4) ?*SDL_Window;

... at which point the next logical step would be to make the type parameter of @extern inferred and merge it with extern the keyword. Something similar could then be done with export/@export to present a unified interface.

@expikr
Copy link
Contributor

expikr commented May 21, 2024

Extending @zzyxyzz 's suggestion, I wonder if perhaps we should do away with function declaration syntax entirely for extern symbols, instead just treat it just like any other identifier bindings, akin to how @import works?

// forward type decl
pub const createWindow: fn([*:0]const u8, c_int, c_int, c_int, c_int, u32) align(4) ?*SDL_Window = @extern(.{.lib="SDL", .name="SDL_CreateWindow"}); 

// coerced type decl
pub const createWindow = @as( 
    fn([*:0]const u8, c_int, c_int, c_int, c_int, u32) align(4) ?*SDL_Window,
    @extern(.{.lib="SDL", .name="SDL_CreateWindow"}) 
);

This also makes it easier to declare a "header"-like file containing namespaced function signatures and entrypoint config:

const SDL = @import("SDLheader.zig"); 

// forward
pub const createWindow: SDL.CreateWindow.signature = @extern(SDL.CreateWindow.entrypoint); 

// coerced
pub const createWindow = @as(SDL.CreateWindow.signature, @extern(SDL.CreateWindow.entrypoint));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants