C:\Temp>type repro.cpp
#include <iostream>
#include <locale>
#include <type_traits>
#include <exception>
using namespace std;
namespace
{
struct deletable_facet : public codecvt_byname<wchar_t, char, mbstate_t>
{
deletable_facet(const std::string& name) : codecvt_byname<wchar_t, char, mbstate_t>(name.c_str()) { }
~deletable_facet() = default;
};
}
wstring FromNarrowString(const char* from, const char* to, const locale& l)
{
const deletable_facet cvt{ l.name() };
mbstate_t mbstate{};
const size_t externalSize = to - from;
wstring resultWStr(externalSize, '\0');
const char* from_next; wchar_t* to_next;
// Issue number 3, cvt.in returns an error.
codecvt_base::result result = cvt.in(mbstate, from, to, from_next, &resultWStr[0], &resultWStr[resultWStr.size()], to_next);
if (result != codecvt_base::ok)
{
throw std::runtime_error("Error converting locale multibyte string to UNICODE");
}
resultWStr.resize(to_next - &resultWStr[0]);
return resultWStr;
}
int main()
{
// Issue number 1. The locale name should not be empty according to the reporter. Other compilers returns "C".
if (std::locale("").name().empty())
{
std::cout << "locale name should not be empty\n";
return -1;
}
// Issue number 2. Microsoft's STL throws "bad locale name" for valid locales that ends with ".utf8" or "UTF-8".
for (const char* localName : { "en_US.utf8", "en_US.UTF-8" })
{
try
{
const string localMBString = "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9d\x84\x8b";
const wstring wideStr = L"zß水𝄋";
locale l{ localName };
if (FromNarrowString(localMBString.c_str(), localMBString.c_str() + localMBString.length(), l) != wideStr)
return -1;
}
catch (const std::exception& ex)
{
std::cout << ex.what() << std::endl;
return -1;
}
}
std::cout << "success\n";
return 0;
}
C:\temp>cl /EHsc /W4 /WX .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29009.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
repro.cpp
Microsoft (R) Incremental Linker Version 14.27.29009.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:repro.exe
repro.obj
C:\temp>repro
locale name should not be empty
Describe the bug
This was reported at Developer Community where several issues were mentioned.
Command-line test case
Expected behavior
It should print success. That's what GCC does. Click to run with compiler explorer
STL version
Microsoft Visual Studio Community 2019 Preview
Version 16.7.0 Preview 3.1
Additional context
Also tracked by DevCom-330322 and VSO-679264 / AB#679264."