Yes, this is also my observation.

For msvcrt40.dll it would be quite tricky as msvcrt40.dll itself does
not export _wassert. So it would be needed via GetModuleHandleA to get
the msvcrt.dll and call msvcrt's _wassert even for msvcrt40.dll builds.
In case msvcrt.dll is not loaded or does not provide _wassert, then
calling msvcrt40.dll's _assert should be safe.

On Monday 08 September 2025 18:32:19 Kirill Makurin wrote:
> I see, so all affected CRTs should also have _wassert. Then it should to be 
> easy enough to _fix_ _assert.
> ________________________________
> From: Pali Rohár <[email protected]>
> Sent: Tuesday, September 9, 2025 3:26 AM
> To: Kirill Makurin <[email protected]>
> Cc: mingw-w64-public <[email protected]>
> Subject: Re: Always map assert to _wassert for msvcr80.dll and later?
> 
> It looks like that those translation modes were introduced in msvcr80
> and are not available in older VC++ versions (like msvcr71, 70, 40, ...).
> They were included into msvcrt.dll system os library in some Windows
> version. And because system os msvcrt40.dll just redirects calls to
> system os msvcrt.dll, they may be available also in msvcrt40.dll.
> 
> So non-affected should be: crtdll.dll, msvcrt10.dll, msvcrt20.dll,
> msvcr40d.dll, msvcrtd.dll, msvcr70.dll, msvcr70d.dll, msvcr71.dll,
> msvcr71d.dll.
> 
> Conditionally affected based-on OS are: msvcrt40.dll and msvcrt.dll.
> 
> And all other libs are always affected.
> 
> On Monday 08 September 2025 18:04:55 Kirill Makurin wrote:
> > 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