I think this issue will occur in all CRTs which allows to set translation mode 
to any of _O_{W|U8|U16}TEXT. I mentioned that these translation modes seem to 
work starting with msvcrt40.dll, so anything other than crtdll.dll, 
msvcrt10.dll and msvcrt20.dll should be affected.
________________________________
From: Pali Rohár <[email protected]>
Sent: Tuesday, September 9, 2025 2:59 AM
To: Kirill Makurin <[email protected]>
Cc: mingw-w64-public <[email protected]>
Subject: Re: Always map assert to _wassert for msvcr80.dll and later?

Thanks for info about availability of _wassert.

Do you have exact list of CRT DLL libs which have "broken" _assert in
this way? I think that it is important to know which CRT DLLs are
affected as only based on that we can say what is harder or easier to
implement.

On Monday 08 September 2025 17:54:48 Kirill Makurin wrote:
> Yes, it possible to change assert's behavior with _set_error_mode[1] 
> functions.
>
> Keep in mind that native _wassert is only available starting with msvcr80.dll 
> and in some msvcrt.dll. If we want to do it for all affected CRTs, for CRTs 
> which do not have _wassert, we probably would need to provide our version 
> which mimics CRT behavior and takes _set_error_mode into account.
>
> Are you sure it is easier to _fix_ _assert?
>
> [1] 
> https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/set-error-mode
> ________________________________
> From: Pali Rohár <[email protected]>
> Sent: Tuesday, September 9, 2025 2:45 AM
> To: Kirill Makurin <[email protected]>
> Cc: mingw-w64-public <[email protected]>
> Subject: Re: Always map assert to _wassert for msvcr80.dll and later?
>
> assert does not have to print error to console. For GUI applications it
> prints error via MessageBox. And the default console output can be
> changed to GUI MessageBox also for console application some CRT call
> (I do not not right now how is that function called but there is some
> option).
>
> My idea was that _assert replacement would just convert its narrow
> strings to wide strings and call _wassert function.
>
> On Monday 08 September 2025 17:42:10 Kirill Makurin wrote:
> > I wonder how many people would call _assert function directly, since it is 
> > Microsoft-specific stuff. If such usage is a thing, it would make sense.
> >
> > Maybe we could always map assert to _wassert and provide a working 
> > replacement (for CRTs which do not have it) which prints message using 
> > fwprintf and calls abort()?
> > ________________________________
> > From: Pali Rohár <[email protected]>
> > Sent: Tuesday, September 9, 2025 2:36 AM
> > To: Kirill Makurin <[email protected]>
> > Cc: mingw-w64-public <[email protected]>
> > Subject: Re: Always map assert to _wassert for msvcr80.dll and later?
> >
> > Personally I do not like those #ifdes for specific CRT version in header
> > files and in past I tried to remove them as many as possible to make
> > header files code more cleaner and not dependent on msvcrt vs UCRT
> > changes. That is why I rather suggested to "fix" the _assert function,
> > so also manual call to _assert function would work (which may be useful
> > when wrapping assert into custom function and want to propagate
> > line/file of the caller).
> >
> > I do not think that the wchar_t[] vs char[] array size is a problem.
> > Assert strings are not such huge.
> >
> > On Monday 08 September 2025 17:29:19 Kirill Makurin wrote:
> > > I did a very quick test and it seems that _O_{U8|U16|W}TEXT translation 
> > > modes are working starting with msvcrt40.dll, so we shouldn't bother 
> > > about this being an issue for msvcrt20.dll and older.
> > >
> > > assert.h already maps assert to _wassert when _UNICODE or UNICODE macros 
> > > are defined. I think we could just extend this condition to include 
> > > `__MSVCRT_VERSION__ >= 0x0800 || defined (_UCRT)`, and if we want to do 
> > > it for msvcrt.dll, `__MSVCRT_VERSION__ == 0x0600`.
> > >
> > > The only drawback I see is that stored strings will be wchar[] instead of 
> > > char[], resulting in larger binaries.
> > >
> > > ________________________________
> > > From: Pali Rohár <[email protected]>
> > > Sent: Tuesday, September 9, 2025 2:15 AM
> > > To: Kirill Makurin <[email protected]>
> > > Cc: mingw-w64-public <[email protected]>
> > > Subject: Re: Always map assert to _wassert for msvcr80.dll and later?
> > >
> > > Now I see that MS documents that _O_U8TEXT does not work together with
> > > printf and hence the assert does not print anything when _O_U8TEXT is
> > > set on stderr.
> > >
> > > https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode
> > >
> > > Instead of redirecting the assert via #define to _wassert, I would
> > > rather propose to overrride _assert symbol for those affected import
> > > libraries and fix it to work also for _O_U8TEXT.
> > >
> > > On Monday 08 September 2025 19:03:09 Pali Rohár wrote:
> > > > Hello,
> > > >
> > > > This is not problem of assert, but rather of the fprintf which assert
> > > > calls. Same problem can be triggered by using the plain 
> > > > fprintf(stderr,...)
> > > > instead of assert(0).
> > > >
> > > > So I do not think that it makes sense to remap assert as basically all
> > > > functions which calls fprintf(stderr,...) are affected.
> > > >
> > > > Is not it just the _O_U8TEXT which is broken?
> > > >
> > > > On Monday 08 September 2025 15:38:09 Kirill Makurin wrote:
> > > > > Consider the following code:
> > > > >
> > > > > ```
> > > > > #include <assert.h>
> > > > > #include <fcntl.h>
> > > > > #include <io.h>
> > > > > #include <stdio.h>
> > > > >
> > > > > int main (void) {
> > > > >   _setmode (_fileno (stderr), _O_U8TEXT);
> > > > >   assert (0);
> > > > >   return 0;
> > > > > }
> > > > > ```
> > > > >
> > > > > When compiled with MSVC, it properly prints message about failed 
> > > > > assertion. When it is compiled with mingw-w64's headers 
> > > > > (Msys2/UCRT64) it produces no output.
> > > > >
> > > > > mingw-w64's assert.h maps assert() macro to _wassert only when 
> > > > > _UNICODE or UNICODE is defined. MSVC's assert.h always maps assert() 
> > > > > macro to _wassert and even no longer exposes _assert function.
> > > > >
> > > > > How about we always map assert() macro to _wassert for msvcr80.dll 
> > > > > and later? Since we also emulate _wassert for msvcrt.dll, it should 
> > > > > be OK to map it to _wassert for msvcrt.dll as well.
> > > > >
> > > > > - Kirill Makurin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to