On Tue, 20 Sep 2022, Pali Rohár wrote:
There are many, many different variants of inline behaviour - C89 inline,
C99 inline, static inline, extern inline, gnu_inline, etc. There's a couple
different styles used here; all the inline functions that we're talking
about here have static inline linkage - which doesn't require any external
linkage version of the function.
When dealing with the other ones that do require external linkage to be
present, there's a whole rat's nest of potential issues, since sometimes one
compiler never tries to use the external version, but other compilers do,
etc.
FWIW a few more side notes about inline functions; the issue is that they
need to work in whichever mode (C89, C99, or C++) that the user chooses to
build with. In practice, this has boiled down to essentially two choices;
"extern inline __attribute__((gnu_inline))" for inlines where we do have
an extern definition somewhere (also, see __CRT_INLINE in _mingw.h), and
plain "static inline" for cases where we don't have an extern definition.
The static inline case has got the disadvantage that if you take the
address of it, you get a different address in each translation unit that
refers to it. (The C++ style inline, which gets comdat folded across
object files that have instantiated it, is nicer in this aspect, but isn't
available equally in all language modes.)
But this is any case beside the point here; if we should change these
things, this should be the sole topic of the patches.
Hello! Thank you very much for all those details. I did not investigated
everything yet, just small subset. But runtime I mean all of them which
you mentioned (from mingw-w64-crt to libgcc/stdc++...). Public
structures and dll libs are problematic. I was planning to look at it
what is different, how and what can be done to achieve binary
compatibility.
The main issue which I see is that if you "compile" source code (gcc -c)
of some application then it already reference ucrt symbols (if mingw-w64
runtime was compiled for ucrt) because header files automatically inline
some ucrt functions. Same for msvcrt.
I see that mingw-w64 crt is compiled with "-D__MSVCRT_VERSION__=0x700"
which you mentioned, and which should "workaround" above issue.
So if this issue can be "fixed" then building static libraries can be
CRT independent.
It can at least currently be fixed, for object files that don't use any
exotic features. Things like libgcc (in a statically linked form) most
probably can easily be made compatible with both, if it isn't already (I
would kinda expect it to).
I believe libstdc++ uses a much wider area of the CRT though, at least I
know that libc++ uses lots of the locale functions - so those might be
harder.
Such a plan to gradually reduce the object file level differences between
UCRT and msvcr* cases, to ease interoperability, sounds reasonble to me. I
won't mind patches to move _snprintf and _scprintf to extern definitions
just like e.g. printf today - but just for clarity, remove the inlines in
the headers in that case, so they're consistent with the rest. And make
the reasoning clear in the commit message, that you're doing it with the
intent to reduce object file level differences between UCRT and msvcrt.
As an aid in making object files that work with environments, maybe it
would be useful with e.g. a define like __CRT_AGNOSTIC__ (or a better
name), which would hide all the details that differ (e.g. the contents of
struct threadlocinfo, and _iobuf) and all inline functions. For _iobuf,
there's very few applications out there that touch it, but threadlocinfo
is used by ctype.h.
For ctype.h, I'm not sure if it's possible to avoid the issue by making
_ischartype_l an extern function instead of an inline macro - but that
certainly would have a performance impact.
Another CRT portability issue which is less obvious, is that e.g. the
printf functions use different format attributes (ms_printf vs
gnu_printf), and similarly, the format defines like PRId64 expand to %lld
vs %I64d. Then again, while %lld is preferred for UCRT, I would expect
that it does handle the legacy form %I64d too, so for __CRT_AGNOSTIC__, I
guess it could use the older forms.
// Martin
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public