On Fri, 18 Oct 2024, Pali Rohár wrote:
Hello, in recent commit 797b4a6b5191 ("headers: Expose the wchar ctype
_l functions for msvcrt.dll for Vista") was added following pattern:
#if __MSVCRT_VERSION__ >= 0x800 || (__MSVCRT_VERSION__ == 0x700 && _WIN32_WINNT
>= 0x0600)
/* These are available since msvcr80.dll, and in msvcrt.dll since Vista. */
_CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
...
#endif
In my opinion, this is wrong because __MSVCRT_VERSION__ == 0x700 matches
msvcr70.dll library and this library does not provide _iswalpha_l()
function on Windows Vista and neither on any other new versions.
Yes, this is a known drawback of this - we explicitly acknowledged this
when coming up with the solution, that we can't distinguish between
msvcrt.dll and msvcr70.dll.
It's not ideal, but we wanted a fix we could push soon, to unbreak
building libc++ with msvcrt.dll.
I understand the point of the commit - to make those functions visible
when compiling against system msvcrt.dll library for Vista+ and at the
same time to hide these functions for pre-msvcr80 libraries and
pre-Vista msvcrt.dll.
It is quite ambiguous what "__MSVCRT_VERSION__ == 0x700" mean as it is
used for both msvcrt.dll and also msvcr70.dll. But msvcrt.dll and
msvcr70.dll provides different set of symbols.
I think that this can be fixed by one of the following options:
Option 1) Introduce a new define for compilation against system
msvcrt.dll library, e.g. -D__MSVCRT_VERSION_SYSTEM__ and write that
check as:
#if __MSVCRT_VERSION__ >= 0x800 || (defined(__MSVCRT_VERSION_SYSTEM__) &&
_WIN32_WINNT >= 0x0600)
/* These are available since msvcr80.dll, and in msvcrt.dll since Vista. */
_CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
...
#endif
Option 2) As system msvcrt.dll library has same name as library from
Visual C++ 4.2 - 6.0 versions and is backward compatible with them, so
change msvcrt-os version in file mingw-w64-headers/configure.ac from
0x700 to 0x600:
msvcrt*)
default_msvcrt_version=0x600
and then change check in header file as:
#if __MSVCRT_VERSION__ >= 0x800 || (__MSVCRT_VERSION__ == 0x600 && _WIN32_WINNT
>= 0x0600)
/* These are available since msvcr80.dll, and in msvcrt.dll since Vista. */
_CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
...
#endif
This would mean:
* __MSVCRT_VERSION__ >= 0x800 - compiling for msvcr80.dll or new
* __MSVCRT_VERSION__ == 0x600 - compiling for msvcrt.dll
* _WIN32_WINNT >= 0x0600 - compiling for Vista or new
So (__MSVCRT_VERSION__ == 0x600 && _WIN32_WINNT >= 0x0600) would mean
that compiling for msvcrt.dll on Vista+.
What do you think?
Out of these two, I kind of prefer option 2 - we already have a lot of
defines involved; adding yet another one into the mix makes it even more
complex, maybe.
Liu Hao presented another option in the discussion as well - we could also
define __MSVCRT_VERSION__ to another value inbetween, as it currently is
0x700 for msvcr70.dll, we could set it to 0x7FF, so that existing
comparisons with <= and >= behave mostly the same as before, while we can
explicitly check for whether we mean msvcrt.dll or msvcr70.dll in the
places where we want to.
But you're right that technically, msvcrt.dll is more of a 6.0 than a 7.0
msvcrt (although it has gotten many additions on top of the original one
from MSVC 6.0). I guess we could use 0x6FF as well, to allow us to
distinguish that we mean msvcrt.dll as shipped with an OS, including
possibly all the new stuff that come with it in newer versions, rather
than the strict msvcrt.dll from MSVC 6.0.
If we do that, we need to revisit most of our current checks for
__MSVCRT_VERSION__ as well.
// Martin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public