On Monday 30 December 2024 23:40:31 Pali Rohár wrote: > On Monday 30 December 2024 18:50:57 Pali Rohár wrote: > > On Monday 30 December 2024 15:32:16 Martin Storsjö wrote: > > > On Thu, 12 Dec 2024, Martin Storsjö wrote: > > > > > > > On Thu, 12 Dec 2024, LIU Hao wrote: > > > > > > > > > 在 2024-12-12 21:17, Martin Storsjö 写道: > > > > > > On Thu, 28 Nov 2024, Pali Rohár wrote: > > > > > > > msvcrt.dll preinstalled as part of the Windows system provides > > > > > > > more > > > > > > > functions than the original Visual C++ 6.0, but still it is > > > > > > > compatible with > > > > > > > the original version. So setting __MSVCRT_VERSION__ to 0x600 > > > > > > > for msvcrt.dll > > > > > > > build is relatively sane option. > > > > > > > > > > > > > > I was considering to use 0x6FF value for this case, but this > > > > > > > would make it > > > > > > > more complicated for applications if they need to know if they > > > > > > > are being > > > > > > > compiled for msvcrt.dll library ABI. They would need to > > > > > > > check if the macro > > > > > > > __MSVCRT_VERSION__ is set to 0x600 (targetting the original > > > > > > > VC++ msvcrt.dll > > > > > > > library) or to value 0x6FFF (targettting the system msvcrt.dll > > > > > > > library). > > > > > > > This looks to be additional complication as it would be > > > > > > > needed to track all > > > > > > > possible values for __MSVCRT_VERSION__. So using just one value > > > > > > > 0x600 for > > > > > > > both cases should be enough because for system version > > > > > > > specific version is > > > > > > > always needed to check also _WIN32_WINNT value. > > > > > > > > > > > > I think this change looks reasonable to me, but I'd like Liu > > > > > > Hao, who suggested the 0x6FF version, to follow up here. > > > > > > > > > > I'm fine with this change, too. > > > > > > > > Thanks, I pushed this one now then. > > > > > > It turns out that this change did cause some breakage in user projects - > > > see > > > https://github.com/msys2/MINGW-packages/pull/22907. > > > > > > Also see > > > https://codesearch.debian.net/search?q=if.*__MSVCRT_VERSION__.*0x0*%5B76%5D&literal=0&page=2 > > > - it seems that there are a number of other projects that also have > > > conditionals relating to this, which also may run into trouble. > > > > > > (E.g. with old mingw.org headers, functions like _aligned_malloc used to > > > be > > > guarded within "#if __MSVCRT_VERSION__ >= 0x0700", so some projects either > > > check __MSVCRT_VERSION__ to know whether it is available, or even try to > > > set > > > __MSVCRT_VERSION__ themselves in order to opt in to using such functions, > > > that were available in msvcrt.dll since XP.) > > > > > > Not saying that this requires revisiting our decision, but it may cause > > > some > > > amount of confusion and breakage in existing user code out there. > > > > > > // Martin > > > > That is not good. But I do not know what can be done better. If the > > application is using #if __MSVCRT_VERSION__ >= ... and one of the > > preprocessor branch result in broken compiled application then it is > > obviously bug in application. > > > > But I do not know what to do with it. Either we need to say that the > > whole __MSVCRT_VERSION__ macro is now broken because it is wrongly used > > by applications and we should rather deprecate it (by providing some > > fixed value to let application compile) and create a new macro e.g. > > __MSVCRT_VERSION_REAL__ which would contain the real version. > > > > Or we need to say that it is application bug and do not care about it. > > > > Or maybe completely remove __MSVCRT_VERSION__ macro and always provides > > all function declarations in header files. > > > > But I think that any of those options just cause new problems. This does > > not have a sane solution at all. > > > > Whatever solution is chosen, I would propose to put big warning into > > release notes what is happening and how application code could be > > adjusted. > > I was thinking more about this problem... It looks like that most > "problematic" SW either check or set __MSVCRT_VERSION__ macro against > value 0x0601. > > What about setting __MSVCRT_VERSION__ to value 0x0601 in configure phase > and then in header files just do relaxed check that upper word is 0x06? > > #if (__MSVCRT_VERSION__ >> 8) == 0x06 > ... compiling for system msvcrt.dll ... > #endif > > So whatever 0x06?? value the application code choose, mingw-w64 header > files would interpret it as using system msvcrt.dll. > > If I'm looking correctly at this, it should also fix the problem with > OSGeo/gdal project. > > And maybe instead of 0x0601 set it in configure phase to 0x06FF what > Liu Hao suggested? > > > PS: Nice tool for regex searching across public git repositories is > sourcegraph.com: > https://sourcegraph.com/search?q=context:global+if.*__MSVCRT_VERSION__.*0x&patternType=regexp&sm=0
To continue my investigation, I finally found the documentation from where are those 0x0601 values coming from. In mingw32 project is this: https://sourceforge.net/p/mingw/mingw-org-wsl/ci/5.1-trunk/tree/mingwrt/msvcrt-xref/msvcrt.def.in * Note that mapping of symbols is directed by __MSVCRT_VERSION__; * for the MSVCRT.DLL versions shipped with the various versions of * MS-Windows, this must be a 32-bit unsigned long value with the * high order 16-bits set to zero, and the low order 16-bits set * to the appropriate platform specific hexadecimal value:-- * * NT4 0x0400UL * Win98 0x0410UL * Win98-SE 0x0412UL * Win2K 0x0500UL * WinXP 0x0501UL * Vista 0x0600UL * Win7 0x0601UL * * Conversely, to map symbols exported by the non-free MSVCRxx.DLL * variants shipped with MSVC, __MSVCRT_VERSION__ is specified with * its low order 20-bits set to zero, while the high order 12-bits * are set to identify the the DLL version of interest:-- * * MSVCR70.DLL 0x07000000UL * MSVCR71.DLL 0x07100000UL * MSVCR80.DLL 0x08000000UL * MSVCR90.DLL 0x09000000UL * MSVCR100.DLL 0x10000000UL * MSVCR110.DLL 0x11000000UL * MSVCR120.DLL 0x12000000UL But it looks like that those "big" numbers are not used in the header files of mingw32. Seems that those "big" numbers are only for the msvcrt.def.in templating. Because in header files there are checks like this: #if __MSVCRT_VERSION__ >= __MSVCR61_DLL || _WIN32_WINNT >= _WIN32_WINNT_WIN2K ... #endif Or: #if __MSVCRT_VERSION__ >= __MSVCR80_DLL ... #endif Or: #if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA ... #endif In mingw32 file include/msvcrtver.h is this content: /* When it is intended to link an application with any one of the * MSVC version specific MSVCRxx.DLL libraries, rather than with the * OS default MSVCRT.DLL, the particular substitute MSVCRxx.DLL may * be specified as any one of the following... */ #define __MSVCR60_DLL 0x0600 #define __MSVCR61_DLL 0x0601 #define __MSVCR70_DLL 0x0700 #define __MSVCR71_DLL 0x0701 #define __MSVCR80_DLL 0x0800 #define __MSVCR90_DLL 0x0900 #define __MSVCR100_DLL 0x1000 #define __MSVCR110_DLL 0x1100 #define __MSVCR120_DLL 0x1200 #ifndef __MSVCRT_VERSION__ /* This may be set, when the intent is to link with any of the above * non-freely distributable MSVCRxx.DLL libraries, rather than with the * pseudo-free MSVCRT.DLL provided as an OS component. High byte is the * major version number, low byte is the minor; however, users are advised * to use custom GCC specs files to set this, while also substituting the * appropriate library in place of MSVCRT.DLL, rather than to simply set * it directly. * * It should be noted that __MSVCRT_VERSION__ is NOT a good indicator of * evolving MSVCRT.DLL features; that is better accomplished by using the * NTDDI_VERSION setting from the Windows API. Thus, users of MSVCRT.DLL * should NOT set __MSVCRT_VERSION__, leaving us to establish a default, * equivalent to MSVCR60.DLL, which seems reasonably well aligned with * the feature set of the earliest MSVCRT.DLL version we support. */ # define __MSVCRT_VERSION__ __MSVCR60_DLL #endif So it looks like that current mingw32 is setting 0x0600 as default value for __MSVCRT_VERSION__. Next, I looked into mingw-org-wsl git repo history and I found out that in more released mingw32 versions following patterns in header files: /* These require msvcr70.dll or higher. */ #if __MSVCRT_VERSION__ >= 0x0700 _CRTIMP void * __cdecl __MINGW_NOTHROW _aligned_offset_malloc(size_t, size_t, size_t); _CRTIMP void * __cdecl __MINGW_NOTHROW _aligned_offset_realloc(void*, size_t, size_t, size_t); _CRTIMP void * __cdecl __MINGW_NOTHROW _aligned_offset_recalloc(void*, size_t, size_t, size_t, size_t); ... #endif /* This require msvcr70.dll or higher. */ #if __MSVCRT_VERSION__ >= 0x0700 _CRTIMP int __cdecl _set_SSE2_enable (int); #endif /* __MSVCRT_VERSION__ >= 0x0700 */ #if __MSVCRT_VERSION__ >= 0x0800 _CRTIMP int __cdecl __MINGW_NOTHROW _utime32 (const char*, struct __utimbuf32*); _CRTIMP int __cdecl __MINGW_NOTHROW _wutime32 (const wchar_t*, struct __utimbuf32*); _CRTIMP int __cdecl __MINGW_NOTHROW _futime32 (int, struct __utimbuf32*); ... #endif Also there are patterns: #if __MSVCRT_VERSION__ >= 0x0601 _CRTIMP int __cdecl __MINGW_NOTHROW _wstat64 (const wchar_t*, struct __stat64*); #endif /* __MSVCRT_VERSION__ >= 0x0601 */ So it means that those "big" values 0x07000000UL were never used at all in header file, and that values 0x0400UL-0x0601UL for system msvcrt.dll are/were used. Also in all older versions was __MSVCRT_VERSION__ by default set to the 0x0600 value. With all information, it looks now clear why applications are checking __MSVCRT_VERSION__ against 0x0601 value or are changing to higher value. It means that they want Windows 7 APIs. But as mingw32 used in past 0x0600 as default value, we should not have issues with this value if we use it as default too. What is quite problem is the interpretation of __MSVCRT_VERSION__ in mingw-w64 header files. It is because it is interpreted differently in mingw32 and mingw-w64. Interpretation of __MSVCRT_VERSION__ by mingw-w64 is currently: crtdll - 0x000 msvcrt10 - 0x100 msvcrt20 - 0x200 msvcrt40 - 0x400 msvcrt - 0x600 msvcr70 - 0x700 msvcr71 - 0x701 msvcr80 - 0x800 msvcr90 - 0x900 msvcr100 - 0xA00 msvcr110 - 0xB00 msvcr120 - 0xC00 ucrt - 0xE00...0xFFF or >= 0x1400 Different meaning is for following values: Value mingw32 meaning mingw-w64 meaning ------ ------------------ ----------------- 0x0400 msvcrt.dll NT4 msvcrt40.dll 0x0410 msvcrt.dll Win98Fe NONE (could be msvcrt40.dll for >= 0x0400 check) 0x0412 msvcrt.dll Win98Se NONE (could be msvcrt40.dll for >= 0x0400 check) 0x0500 msvcrt.dll Win2K NONE (could be msvcrt40.dll or msvcrt.dll) 0x0501 msvcrt.dll WinXP NONE (could be msvcrt40.dll or msvcrt.dll) 0x0600 msvcrt.dll Vista msvcrt.dll 0x0601 msvcrt.dll Win7 NONE (could be msvcrt.dll for >= 0x0600 check) 0x0A00 NONE msvcr100.dll 0x0B00 NONE msvcr110.dll 0x0C00 NONE msvcr120.dll 0x1000 msvcr100.dll NONE (could be msvcr120.dll for >= 0x0C00 check) 0x1100 msvcr110.dll NONE (could be msvcr120.dll for >= 0x0C00 check) 0x1200 msvcr120.dll NONE (could be msvcr120.dll for >= 0x0C00 check) 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) * Windows 7+ OS system msvcrt.dll version: - #if (__MSVCRT_VERSION__ >= 0x601) || (__MSVCRT_VERSION__ == 0x600 && _WIN32_WINNT >= _WIN32_WINNT_WIN7) - First part will match mingw32 Windows7+ check, second part will match mingw-w64 check * 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 Would be this enough to finally fix those issues with __MSVCRT_VERSION__? _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
