On Thursday 02 January 2025 11:00:43 Pali Rohár wrote: > On Thursday 02 January 2025 11:36:26 Martin Storsjö wrote: > > On Thu, 2 Jan 2025, Pali Rohár wrote: > > > > > > No, 0x0601 for __MSVCRT_VERSION__ doesn't mean Windows 7. I think you've > > > > made way too much conclusions based on the info in msvcrt.def.in, which > > > > does > > > > not seem to be using the same numbering scheme as the headers. > > > > > > I see, I was wrong, based on that file which I found... > > > > > > > > > > > I believe the version numbering for __MSVCRT_VERSION__ in headers was > > > > meant > > > > to use both the msvcrXX.dll version numbers, just like we do, but also > > > > based > > > > on the actual embedded version number of the msvcrt.dll that shipped > > > > with > > > > the OS. > > > > > > > > I don't have a copy of msvcrt.dll from win9x or older versions handy for > > > > looking at, but I have a set of the modern ones. Using "peres -v > > > > msvcrt.dll" > > > > (the "peres" tool from the "pev" or "readpe" package on Ubuntu), I'm > > > > getting > > > > the following version: > > > > > > > > Win2k 6.1.8637.0 > > > > WinXP 7.0.2600.5512 > > > > Vista 7.0.6002.18551 > > > > Win7 7.0.7601.17744 > > > > > > So for completeness, I run peres -v on these system versions: > > > > > > NT4.0 4.20.0.6201 > > > Win98 5.0.0.7128 > > > Win98SE 6.0.8397.0 > > > WinMe 6.1.8637.0 > > > Win2k 6.1.8637.0 > > > Win2ksp3 6.1.9359.0 > > > Win2ksp4 6.1.9844.0 > > > WinXP 7.0.2600.0 > > > WinXPsp1 7.0.2600.1106 > > > WinXPsp2 7.0.2600.2180 > > > WinXPsp3 7.0.2600.5512 > > > WinXPx64 7.0.3790.1830 > > > > > > NT4 msvcrt.dll has same set of symbols as VC4.2 msvcrt version, Win98 FE > > > has same set as VC5.0SP1, and Win98 SE has same as as VC6.0. So it looks > > > like that version numbers from peres for NT4/Win98 matches the VC++ > > > versions. > > > > Yep. And to make things clear - msvcrt.dll in XP doesn't have the same set > > of symbols as the real msvcr70.dll, right? So the divergence started at that > > point (and/or at the 6.1 versions used in 2k and Me) > > Yes. The correct list of symbols for msvcrt.dll in XP and in msvcr70.dll > are already documented in mingw-w64 files: > > mingw-w64-crt/lib-common/msvcrt.def.in > mingw-w64-crt/lib32/msvcr70.def.in > > > > > This also lines up perfectly with some of the ifdefs you referenced - > > > > e.g. > > > > _aligned_malloc exists in msvcrt.dll since XP, and is guarded by > > > > __MSVCRT_VERSION__ >= 0x0700. And _wstat64 which is guarded by > > > > __MSVCRT_VERSION__ >= 0x0601 is available since Win2k. > > > > > > That make sense. I checked in our msvcrt.def.in and _wstat64 symbol is in > > > Windows ME/2000 section. > > > > > > > So the mythical __MSVCR61_DLL means Win2k. > > > > > > Yes, that would make sense. > > > > > > > > So, based on this investigation, I think that changing default value > > > > > of > > > > > __MSVCRT_VERSION__ again should not be needed. I would suggest to just > > > > > adjust checks in mingw-w64 header files for: > > > > > > > > > > * OS system msvcrt.dll version (any OS): > > > > > - #if __MSVCRT_VERSION__ > 0x400 && __MSVCRT_VERSION__ < 0x700 > > > > > - This will match any mingw32 OS system msvcrt.dll version except > > > > > the Windows NT4 > > > > > - It does not conflict with neither mingw-w64 msvcrt40 (== 0x400) > > > > > nor with msvcr70 (== 0x700) > > > > > > > > I don't think they used __MSVCRT_VERSION__ < 0x600 for anything, other > > > > than > > > > potentially msvcrXX.dll versions just like we do. > > > > > > Probably yes. So the condition could be: > > > > > > #if __MSVCRT_VERSION__ >= 0x600 && __MSVCRT_VERSION__ < 0x700 > > > > Yes, that sounds good to me. > > > > > > > * msvcr100+: > > > > > - (__MSVCRT_VERSION__ >= 0xA00 && __MSVCRT_VERSION__ < 0x1000) || > > > > > (__MSVCRT_VERSION__ >= 0x1000) > > > > > - First part is for mingw-w64, second for mingw32 > > > > > > > > > > * msvcr110+: > > > > > - (__MSVCRT_VERSION__ >= 0xB00 && __MSVCRT_VERSION__ < 0x1000) || > > > > > (__MSVCRT_VERSION__ >= 0x1100) > > > > > - First part is for mingw-w64, second for mingw32 > > > > > > > > > > * msvcr120+: > > > > > - (__MSVCRT_VERSION__ >= 0xC00 && __MSVCRT_VERSION__ < 0x1000) || > > > > > (__MSVCRT_VERSION__ >= 0x1200) > > > > > - First part is for mingw-w64, second for mingw32 > > > > > > > > I don't think we should do anything to complicate things for numbered > > > > msvcrXX.dll here - using anything other than msvcrt.dll and UCRT is > > > > exceedingly rare. (I only practically know of two cases; you, and VLC > > > > did > > > > need to target msvcr120*.dll for Windows Store distribution at some > > > > point, > > > > and that's no longer relevant for them.) > > > > > > Ok. It was just a suggestion for completeness. As nobody complained > > > then it is not needed. > > > > > > > > Would be this enough to finally fix those issues with > > > > > __MSVCRT_VERSION__? > > > > > > > > I don't think this would make any difference here at all. > > > > > > > > > > > > I believe that the issues that can be caused by our changes fall into > > > > two > > > > classes: (Sorry, I didn't browse all the code search results to see what > > > > other concrete cases there were.) > > > > > > > > - Projects that look at __MSVCRT_VERSION__ and conditionally compile > > > > things. > > > > This may lead to projects building with fewer features (by skipping > > > > things > > > > that would require a newer msvcrt.dll), or trying to use extra compat > > > > routines that wouldn't be necessary. Or there can be clashes, if they > > > > see > > > > our __MSVCRT_VERSION__ and conclude that function X isn't provided, and > > > > they > > > > try to provide their own replacement function X, and they can get > > > > duplicate > > > > conflicting definitions. > > > > > > > > Or the ifdefs are only tested in one configuration and simply break in > > > > the > > > > other one, like I think was the case in the linked msys2 issue. > > > > > > > > Addapting our header ifdefs to also recognize different values from > > > > mingw.org toolchains won't make any difference here at all. > > > > > > > > Most of the cases I saw in the code search I browsed earlier seemed to > > > > be > > > > this case - e.g. trying to provide workarounds for 64 bit stat > > > > functions or > > > > similar. I haven't tried compiling them to see if our new definitions > > > > actually cause a problem or not. > > > > > > > > - Projects that themselves try to change __MSVCRT_VERSION__ to expose > > > > more > > > > features, e.g. setting __MSVCRT_VERSION__ to 0x700 to get XP level > > > > features > > > > like _aligned_malloc available. This is mostly harmless for us, even if > > > > it > > > > in corner cases could cause problems (by exposing msvcr70.dll features > > > > when > > > > they actually meant msvcrt.dll/XP - but mingw.org headers also seem to > > > > generally consider the two equal). > > > > > > > > One such case is familiar to me, > > > > https://github.com/FFmpeg/FFmpeg/blob/n7.1/configure#L6036-L6037. But > > > > that > > > > one is only done if the headers are mingw.org headers, not mingw-w64, > > > > so it > > > > doesn't make any difference for us. (It's used for getting specifically > > > > _aligned_malloc.) > > > > > > > > > > > > > > > > So I think the main source of problems for user code is that we used to > > > > default to __MSVCRT_VERSION__ == 0x700 and now we default to something > > > > else. > > > > > > > > We could consider defaulting to 0x0601 (or 0x06FF); this would pick the > > > > same > > > > branch as before, for all the cases of __MSVCRT_VERSION__ >= 0x0601. So > > > > it > > > > could reduce the amount of breakage that we cause. > > > > > > > > For any code that checks __MSVCRT_VERSION__ >= 0x700 though, things > > > > would > > > > unfortunately change. > > > > > > > > // Martin > > > > > > I see. But if we change the default value again then it would be > > > necessary to updates also mingw-w64 headers with new check for system > > > msvcrt.dll value. Something what I wrote above (just first two cases). > > > > Yes - we could change that in any case, to allow any value between 0x600 and > > 0x6FF, in case users override it. > > > > Then for our default value; either 0x0601 or 0x06FF would be ok with me. At > > this point, I'm actually leaning towards 0x06FF. > > > > This makes it clearer that it's not specifically the 2k/Me version (not == > > 0x0601), and that it's "almost" the 0x0700 that we had before (even if that > > "almost" wouldn't functionally have any effect anywhere). With 0x06FF we > > would get the right behaviour if there's any condition which is "> 0x0601" > > (not sure if that one exists anywhere though). > > This makes sense. Better to use 0x06FF. > > > (This also leaves the door open if we'd want to add more header ifdefs to > > differentiate between the various versions of msvcrt.dll. Not saying that we > > should, but it makes it possible.) > > > > Then, the only issue is just that we no longer claim to be >= 0x0700 as we > > did before - and this is by design, as we want to differentiate between the > > real msvcr70.dll and the somewhat-similar-to-msvcr70.dll msvcrt.dll from XP > > and similar. > > > > // Martin
Another idea how to handle this problem, so the application would have access to declaration of >= 0x0700 functions. Remove all __MSVCRT_VERSION__ checks in mingw-w64 header files which hide msvcr* functions, and then revert back the default __MSVCRT_VERSION__ value to 0x0700. _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public