2

I have a strange problem with system error messages obtained from std::error_code on Windows. When I build and run test program 1 (see below) using my locally installed Visual Studio, error messages for all system error codes come out as "unknown error". On the other hand, when building and running the same program on the same version of Visual Studio through Godbolt / Compiler Explorer, proper error messages are produced (see test program 1 and output below).

I tested this with Visual Studio 2022 version 17.3.3 (MSVC 19.33) on Windows 10.

I am using the community version of Visual Studio.

I have tried to build locally using the developer command prompt (cl test.cpp), using a Visual Studio console project (all settings at default), and using a Visual Studio CMake project (all settings at default). It makes no difference. In all cases, all error messages come out as "unknown error".

I am not experienced with Visual Studio, so I may definitely be making a very basic mistake.

Any advice as to how I can further diagnose the problem is also welcome.

Output from test program 1 (see below) when built and run through Godbolt / Compiler Explorer:

message = 'The directory is not empty.' (193331629)

Output from test program 1 (see below) when built and run locally:

message = 'unknown error' (193331629)

Output from test program 2 (see below) when built and run locally:

message = 'The directory is not empty.' (193331629)

Test program 1:

#include <windows.h>
#include <system_error>
#include <stdio.h>

int main()
{
    std::error_code ec(ERROR_DIR_NOT_EMPTY, std::system_category());
    printf("message = '%s' (%lld)\n", ec.message().c_str(), static_cast<long long>(_MSC_FULL_VER));
}

Test program 2 (for contrast):

#include <windows.h>
#include <stdio.h>

int main()
{
    char buffer[256];
    DWORD len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ERROR_DIR_NOT_EMPTY, 0, buffer, 255, NULL);
    while (len > 0 && (buffer[len - 1] == '\n' || buffer[len - 1] == '\r'))
        --len;
    buffer[len] = '\0';
    printf("message = '%s' (%lld)\n", buffer, static_cast<long long>(_MSC_FULL_VER));
}
Kristian Spangsege
  • 2,903
  • 1
  • 20
  • 43
  • I do not have visual studio installed locally to test this, but indeed Godbolt shows `message = 'The directory is not empty.' (193331629)` for both of your example programs using msvc 19.33 https://godbolt.org/z/no435f735 – Cory Kramer Sep 02 '22 at 14:58
  • 1
    You could try to step into the functions in the debugger. Note that both the pdbs (on the Microsoft symbol servers) and the source code (see e.g. [here](https://stackoverflow.com/questions/49048673/where-are-the-vs2015-ucrt-source-files)) for the ucrt is available, so you should be able to see where it goes wrong. – Sedenion Sep 02 '22 at 15:34
  • @Sedenion, that lead me to understand the problem. Thanks. – Kristian Spangsege Sep 02 '22 at 23:21

1 Answers1

3

Ok, the problem in my case is that the system locale is set to "en-GB" and not "en-US".

If I pass language identifier 2057 (en-GB) to FormatMessage() I get no error message, but if I pass 1033 (en-US), I do.

So far, I have not been able to change the system-level locale, but even if it can be done, it seems rather suboptimal that system error messages fail to work if my system locale is set to "en-GB".

I wonder if there is a rational idea behind this behavior, or if it is just plain broken.

In any case, the solution in my case, I think, is to introduce a custom error category that invokes FormatMessage() with a language identifier of 0 (see https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage), and then forward to the native system error categeory in the functions that deal with mapping to generic error condition.

Kristian Spangsege
  • 2,903
  • 1
  • 20
  • 43
  • 1
    https://support.microsoft.com/en-us/windows/language-packs-for-windows-a5094319-a92d-18de-5b53-1cfc697cfca8 – Hans Passant Sep 02 '22 at 22:49
  • @HansPassant I did have the relevant language packs installed (for both "en-GB" and "en-US"), so that was not the problem. I figured out how to change the system locale (through "administrative language settings"), and that helped. Still, it seems odd that it does not work "out of the box" (system locale was apparently set to "en-GB" by Windows installer). – Kristian Spangsege Sep 02 '22 at 23:18
  • I can reproduce with en-GB. This sounds like a Microsoft bug - literally any message would be better than "unknown error", even in the wrong language. Did you report it to Microsoft? – Etienne Dechamps Jan 27 '23 at 23:42
  • I took the liberty of reporting it myself: https://developercommunity.visualstudio.com/t/std::error_code::message-incorrectly-r/10263529 – Etienne Dechamps Jan 28 '23 at 11:19