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.

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

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

Reply via email to