On Monday 10 October 2022 14:25:07 Martin Storsjö wrote:
> Historically, the _CRTIMP macro comes from how it is used in upstream
> msvcrt; you can link the CRT either statically or dynamically. If intending
> to link statically, _CRTIMP expands to nothing, while if intending to link
> dyanmically, _CRTIMP expands to dllimport. For mingw-w64, there's no option
> to link the full CRT statically, so from user code point of view, there's
> only the dllimport case to care about.

Thank you for explanation, this makes sense.

> But when building code within mingw-w64-crt, _CRTIMP expands to nothing. I
> guess this is generally desireable when implementing some of the functions
> that are marked _CRTIMP (we generally shouldn't have a dllimport declaration
> of the function visible when we're implementing it).

Hm... if mingw-w64 runtime wants to redefine some function then it needs
to statically link redefined function into the final executable, right?
So should not in this case completely omit _CRTIMP to ensure that
function does not have dllimport to prevent useless usage of _imp_
pointer wrapper?

> However this can also be tricky, because if it indeed is a data symbol that
> we're overriding/providing in mingw-w64-crt, then having it visible without
> dllimport is fine (when other object files in mingw-w64-crt reference it,
> and both of them will be linked statically, but if it is a symbol that will
> be imported from a DLL file, via the def files, then accessing it without
> dllimport is going to cause unnecessary auto imports and runtime pseudo
> relocs.

Makes sense too, data symbol exported from DLL should be marked with
dllimport when compiling application and also when compiling mingw-w64
runtime.

> So in short, the following two are functionally exactly equivalent - they
> generate the same code in a compiler when you reference it:
> 
>     extern int * __MINGW_IMP_SYMBOL(someDataSymbol);
>   #define someDataSymbol (* __MINGW_IMP_SYMBOL(someDataSymbol))
> and
>     extern int __declspec(dllimport) someDataSymbol;

Thanks! This is what I thought, but I was not fully sure.

> However if you make it
>     extern int _CRTIMP someDataSymbol;
> 
> then you lose the dllimport for any code within mingw-w64-crt that is
> accessing it - leading to unnecessary auto imports and runtime pseudo
> relocs.

Right!

> I think the common pattern within mingw-w64-headers is to simply use the
> first form via the explicit __MINGW_IMP_SYMBOL redirection for any data
> symbols, while _CRTIMP is used for functions only. Exported data symbols in
> the CRT interface generally are problematic anyway. And the define form,
> while kinda unwieldy, gives you a bit more freedoms to check for it with
> ifdef, work around it with undef, etc.

Ok, this is good to know. I did not know what is that preference.

Anyway, why exported functions are defined via _CRTIMP? Should not be
also be defined via __MINGW_IMP_SYMBOL/dllimport to avoid generating
unnecessary thunk/wrapper for mingw-w64 runtime code?


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to