digitalmars.D.learn - BetterC Name Mangling Linker Errors
- MyNameHere (56/56) Jul 27 2022 I have included the source to a simple 64-bit Windows program.
- Dennis (30/35) Jul 27 2022 This is equivalent to `WNDCLASSEXA WindowClass =
- MyNameHere (1/1) Jul 27 2022 Thank you, that seems to have been the source of the error.
I have included the source to a simple 64-bit Windows program. It compiles and runs fine with ```dmd -m64 -L="/Subsystem:Windows" -L="/Entry:Main" Main.d```. But compiling with ```-betterC``` using the following throws up a linker error, ```dmd -m64 -betterC -L="/Subsystem:Windows" -L="/Entry:Main" Main.d```: ```Main.obj : error LNK2019: unresolved external symbol _D4core3sys7windows7winuser11WNDCLASSEXA6__initZ referenced in function Main``` And I'm not sure why. ```d import core.sys.windows.winuser; import core.sys.windows.winbase; pragma(lib, "User32.lib"); pragma(lib, "Kernel32.lib"); extern(Windows) void Main(void* Instance) { WNDCLASSEXA WindowClass; with (WindowClass) { cbSize = WindowClass.sizeof; lpfnWndProc = &WindowProc; hInstance = Instance; hCursor = LoadCursor(null, IDC_ARROW); lpszClassName = "Window"; } RegisterClassExA(&WindowClass); void *WindowHandle = CreateWindowExA(0, "Window", "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, null, null, Instance, null); ShowWindow(WindowHandle, SW_MAXIMIZE); MSG Message; while (GetMessage(&Message, null, 0, 0)) { TranslateMessage(&Message); DispatchMessage(&Message); } } extern(Windows) long WindowProc(void* WindowHandle, uint Message, ulong WParam, long LParam) nothrow system { if (Message == WM_DESTROY) ExitProcess(0); return DefWindowProcA(WindowHandle, Message, WParam, LParam); } ```
Jul 27 2022
On Wednesday, 27 July 2022 at 12:26:59 UTC, MyNameHere wrote:```d void Main(void* Instance) { WNDCLASSEXA WindowClass; ```This is equivalent to `WNDCLASSEXA WindowClass = WNDCLASSEXA.init;` If the struct's fields all initialize to 0, the compiler would simply set the variable's bytes to 0, but the definition in druntime gives fields with non-zero default value: ```D struct WNDCLASSEXA { UINT cbSize = WNDCLASSEXA.sizeof; // <-- non zero init UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCSTR lpszMenuName; LPCSTR lpszClassName; HICON hIconSm; } ``` Because of this, the compiler defines an 'init symbol' in druntime that gets copied into your variable to initialize it. Because druntime isn't linked when using BetterC, the linker fails to find the init symbol. I think removing the default initialization will fix it: ```D WNDCLASSEXA WindowClass = void; ```
Jul 27 2022
Thank you, that seems to have been the source of the error.
Jul 27 2022