On Friday 18 October 2024 23:36:06 Martin Storsjö wrote:
> 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.

Make sense, quick fix for unbreak building and better fix later.

> > 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.

Personally I like option 2 more than option 1 too.

> 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.

0x7FF has drawback, that <= and >= does not work for symbols available
in Vista+ msvcrt.dll but which are not available in msvcr70.dll and
msvcr71.dll.

> 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.

It is needed to have special value (like 0x6FF) for __MSVCRT_VERSION__
when doing system version check? Because at the same time it is always
needed to check also for _WIN32_WINNT.

As you pointed out, adding more values or macros just make it more
complex. And another possible value for __MSVCRT_VERSION__ just increase
complexity too.

So in my opinion reusing 0x600 with _WIN32_WINNT could be enough:

    #if (__MSVCRT_VERSION__ == 0x600 && _WIN32_WINNT >= 0x0600)


I think that special value like 0x6FF just increase complexity and still
it would be needed to write code as:

    #if (__MSVCRT_VERSION__ == 0x6FF && _WIN32_WINNT >= 0x0600)


Btw, for completeness, Win98 SE system msvcrt.dll is same as msvcrt.dll
from VC++ 6.0. So targeting older system Windows versions is same as VC++.

> If we do that, we need to revisit most of our current checks for
> __MSVCRT_VERSION__ as well.
> 
> // Martin

Yes, I think that all __MSVCRT_VERSION__ places needs to be revisited.


_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to