On Sunday 21 June 2026 11:34:57 Kirill Makurin wrote: > Pali Rohár <[email protected]> wrote: > > > On Sunday 21 June 2026 06:13:42 Kirill Makurin wrote: > >> > >> IMO, if an application compiled against pre-msvcr80.dll calls > >> > >> _setmode (fd, _O_U8TEXT) > >> > >> It is a clearly bug in an application. It attempts to use a feature which > >> is not supported by that CRT; it will compile but will behave differently > >> than expected. > > > > For msvcrt.dll (Visual C++ 6.0) this is not a bug. It is documented > > behavior in the official documentation for _set_mode: > > https://web.archive.org/web/20010418052903/http://msdn.microsoft.com/library/devprods/vs6/visualc/vccore/_crt__setmode.htm > > > > "A return value of –1 indicates an error, in which case errno is set to > > either EBADF, indicating an invalid file handle, or EINVAL, indicating > > an invalid mode argument (neither _O_TEXT nor _O_BINARY)." > > > > So application can call _setmode (fd, _O_U8TEXT) and check return value > > (with errno) if the _O_U8TEXT is supported or not. > > > > I used this technique lot of times (but not for _setmode). > > From current description for _setmode[1], it sounds like as if you were to > pass an invalid mode, it calls invalid parameter handler. With debug version > of UCRT, it actually triggers an internal assertion.
Yes, but that invalid handler is called only in new versions which already supports the _O_U8TEXT. So the call _setmode (fd, _O_U8TEXT) with valid fd should either pass (new versions, including UCRT) or should fail without invoking invalid handler and returning -1. > >> IMO, Windows-only code must use Unicode whenever possible; the only reason > >> not to is Win9x systems which lack Unicode support. > > > > Which is not the only case of mingw-w64 usage. > > > >> If someone intends to support only Windows 10 and later, using UTF-8 is > >> probably the best solution. However, if they want to support pre-Windows > >> 10 systems, they should use UTF-16; otherwise they will be limited to > >> locale's ANSI code pages. > > > > That is truth. But for people from UNIX world can be UTF-16 a pain I > > understand if the ANSI code page limitation is taken. > > Yes, absolutely. > > And keep in mind all this code page mess on Windows makes this so much worse; > code page used by ANSI functions (e.g. MessageBoxA), code page used for > filenames (e.g. with CreateFileA), code page used for console input, console > output, code page used by CRT global and thread locales. > > >> Basically, CRT has both `_wassert` and support for Unicode translation > >> modes, or neither. If we use `_wassert`, we do not have to worry about > >> `_assert` not working with Unicode translation modes. Otherwise, > >> `_wassert` emulation simply redirects to `_assert`, while doing its best > >> at converting its arguments. > > > > This is a good point. The only problem is with msvcrt40.dll redirector > > (which is since first NT 4.0 version) which does not have _wassert but > > since some OS version it started supporting Unicode translation modes. > > So the detection of _wassert cannot be done via msvcrt40.dll for > > msvcrt40 builds, but rather more smarter. And I'm not sure if it is > > possible to write it correctly in that smart way to correctly detect it. > > And this detection could be too complicated. > > I mentioned this issue in the very first message. Now this is also an issue > for crtdll.dll and msvcrt20.dll which are similarly redirected to msvcrt.dll > on Windows 11. So in any case, the fix for _assert is needed as all those libraries do not have _wassert; and mingw-w64 emulation of _wassert is wrapper around _assert. I would think more about it, how to handle it... maybe I will come up with other / different ideas. > >> IMO, using `alloca` is totally OK as long as it is used carefully. My > >> proposed changes limit allocation sizes to `BUFSIZ` (512) and > >> `FILENAME_MAX` (260), and even try to allocate smaller buffers when we can. > > > > I was thinking about this and I have not come up with better idea. So I > > agree with alloca usage. Buffer with sane upper limit is fine. The only > > problem is that in this way the longer assert string would be truncated. > > But I have no better idea how to handle this situation. > > > > Maybe we if the truncation is going to happen, we can put the "..." at > > the end of buffer to at least visually show that something was truncated > > and "visually shows" that it was expected and has it purpose. > > I was thinking the same idea. I think there's no harm in doing so. > > >> From what I know, CRT stdio functions, when write to terminals, convert > >> strings to code page returned by `GetConsoleOutputCP`. What we must keep > >> in mind is that it interprets original (narrow) strings using code page > >> for active CRT locale (`setlocale`). > > > > Ok. This is important to know and maybe should put this information into > > the mingw-w64 _wassert code. So anybody after us in future will read the > > code, could understand reason why it is implemented in this way. Because > > this codepage stuff is huge and easy to misuse and very easy to forgot > > how it works. > > Good point. > > - Kirill Makurin > > [1] https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
