emscripten-core / emscripten-core/emscripten

std::locale works unexpectedly with unsupported locale

Open
#22,051 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Please include the following in your bug report:

**Version of emscripten/emsdk:**
3.1.54

**Failing command line in full:**
```shell
# emcc
emcc locale_not_support.cpp -o main.js
node main.js

# g++
g++ locale_not_support.cpp -o main
./main
```

Hi, it's a follow-up issue to #2630 and #2636. I'm trying to use `std::locale`. It seems that currently emscripten is not throwing any exceptions when a locale is not supported. It seems the locale name is set as given, but the functionality appears to be the same as the `std::locale::classic()`.

As the code and results shown below, if I tried to print the date, number, etc., of POSIX locale and es_ES.UTF-8. In wasm, the results seem to be the same as the POSIX locale. But its name is set as given, and turns out to be different with the `std::locale::classic()` (POSIX locale) if I simply use `==` for comparison. It may not be a big problem, but I believe there could be some better ways to deal with unsupported locales, like simply returning `std::locale::classic()` whatever the given name is, or throwing exceptions like native execution does.

I saw the commit https://github.com/emscripten-core/emscripten/commit/3aa06ea9f1e5e1bc51eb0b3c7f350ec5095efe9c trying to solve this to make the program fail when the locale is not supported. But it seems it was modified in the later version and now it won't fail given unsupported locales. Is that due to some special considerations?

Thank you very much!

#### Code
```c++
#include
#include
#include
#include

void printNumber(const std::locale& loc) {
std::cout.imbue(loc);
std::cout << "Formatted number: " << std::fixed << std::setprecision(2) << 12345.67 << std::endl;
}

void printDate(const std::locale& loc) {
std::time_t t = std::time(nullptr);
std::tm* tm = std::localtime(&t);
std::cout.imbue(loc);
std::cout << "Formatted date: " << std::put_time(tm, "%c") << std::endl;
}

int main() {
printf("flag before set posix locale\n");
std::locale posix("C");

std::cout << "locale C, name: " << posix.name() << std::endl;
printNumber(posix);
printDate(posix);

std::cout << std::endl;

printf("flag before set spanish locale\n");
std::locale spanish("es_ES.UTF-8");

std::cout << "es_ES.UTF-8, locale name: " << spanish.name() << std::endl;
printNumber(spanish);
printDate(spanish);

std::cout << std::endl;

std::cout << "is C equal?: " << (posix == std::locale::classic()) << std::endl;
std::cout << "is spanish equal?: " << (spanish == std::locale::classic()) << std::endl;
return 0;
}
```

#### Results
```shell
# in wasm:
flag before set posix locale
locale C, name: C
Formatted number: 12345.67
Formatted date: Mon Jun 03 18:36:20 2024

flag before set spanish locale
es_ES.UTF-8, locale name: es_ES.UTF-8
Formatted number: 12345.67
Formatted date: Mon Jun 03 18:36:20 2024

is C equal?: 1
is spanish equal?: 0

# in native (one that doesn't have es_ES.UTF-8 support):
flag before set posix locale
locale C, name: C
Formatted number: 12345.67
Formatted date: Mon Jun 3 19:08:59 2024

flag before set spanish locale
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
Aborted (core dumped)

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.