Zig: Exported functions should be public by default

Created on 1 Aug 2019  路  1Comment  路  Source: ziglang/zig

The windows subsystem detection did not properly work, because the exported WinMain function was not defined with the pub keyword. This caused the @hasDecl builtin to not find the WinMain function and caused the subsystem detection to be wrong. The following example is relevant:

const std = @import("std");
const builtin = @import("builtin");
usingnamespace std.os.windows;

extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;

export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) INT {
    _ = MessageBoxA(null, c"test", c"title", 0);
    @compileLog(subsystem);
    return 0;
}

Without the pub in front of export fn WinMain(... this showed that the subsystem was .Console, whereas with the pub it correctly showed .Windows.

Solution

  1. Always mark a exported function as public internally in the compiler.
  2. Give an error when a exported function is not defined with the pub keyword.
  3. Change the implementation of @hasDecl to also return true for exported functions.

I would like to implement the fix for this, once I know which solution is the best.

proposal

Most helpful comment

I vote for option 3 as export and pub have AFAIK different semantics: pub means that the symbol is visible to importers and export means that the symbol is visible to extern declarations and the linker. It seems most appropriate to change @hasDecl as conflating extern and pub isn't a good idea.

>All comments

I vote for option 3 as export and pub have AFAIK different semantics: pub means that the symbol is visible to importers and export means that the symbol is visible to extern declarations and the linker. It seems most appropriate to change @hasDecl as conflating extern and pub isn't a good idea.

Was this page helpful?
0 / 5 - 0 ratings