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

Reply via email to