Thanks for details about manifest file.

The issue here is that some tests may verify that the function being tested 
handles `errno` correctly, that it sets it when it should, and does not change 
it otherwise. I have `assert (errno == 0)` after successful calls which should 
verify that the functions did not mistakenly change `errno`. I guess it would 
be smarter to save previous `errno` value and test it for it afterwards. I also 
have explicit `_set_errno (0)` after the function has set `errno` as expected.

It just threw me off, I expected `errno` to be set to 0 by default.
________________________________
From: Pali Rohár <[email protected]>
Sent: Friday, November 14, 2025 3:48 AM
To: Kirill Makurin <[email protected]>
Cc: mingw-w64-public <[email protected]>
Subject: Re: errno is set to EINVAL when entering main

Hello!

On Thursday 13 November 2025 06:52:23 Kirill Makurin wrote:
> With msvcr{100,110,120}.dll , `errno` is set to EINVAL when entering main.

It is a problem? I thought that errno value is undefined when entering
into the main function.

> This may also be true for msvcr{80,90}.dll, but I can't figure out how to run 
> executables linked against those CRTs, since they are installed as 
> side-by-side assemblies.

The easiest option is to create external manifest file.

Create a new text file named a.exe.manifest and for msvcr80 put this content:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <dependency>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" 
version="8.0.50727.42" processorArchitecture="x86" 
publicKeyToken="1fc8b3b9a1e18e3b"/>
      </dependentAssembly>
    </dependency>
  </assembly>

After that a.exe can use msvcr80.dll library. Version 8.0.50727.42 is
the RTM release and all redistributable msvcr80 versions support this
one. Normally installed side-by-side assembly version and the dependency
version must match, but the msvcr80 redistributable contains backward
compatibility policy back to the first released RTM version.

If the a.exe is linked against msvcr90.dll then put into a.exe.manifest
this content:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <dependency>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" 
version="9.0.21022.8" processorArchitecture="x86" 
publicKeyToken="1fc8b3b9a1e18e3b"/>
      </dependentAssembly>
    </dependency>
  </assembly>

Other option would be to link manifest file directly into the exe file
but this is not automated by gcc / ld and has to be done manually.

> The following code should reproduce the issue:
>
> ```
> #include <assert.h>
> #include <errno.h>
>
> Int main (void) {
>   assert (errno == 0);
>   return 0;
> }
> ```
>
> I wanted to quickly test whether library I'm working on builds and works with 
> msvcr*.dll, and when I was running the tests, I noticed that all tests for 
> C89/C95/uchar.h conversion functions failed. After small investigation I 
> realized that errno was to EINVAL upon entry to `main`.

Majority of C and POSIX function (maybe all?) do not modify errno when
the function success. So I do not think that it is an issue if errno is
not touched (and stays in the EINVAL state) after successful conversion.
It is up to the caller to set errno to 0 if caller wants to check it on
possible success path.

> Can anyone look into this?
>
> - Kirill Makurin

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

Reply via email to