This is the C++ version of Issue #2630. I didn't realize it was a distinct issue yesterday. Sorry.
The std::locale() constructor taking a locale name must fail when the locale isn't supported. Here's the behaviour I would expect with gcc when the "en_CA.UTF-8" locale is supported in addition to "C":
$ g++ -Wall -o locale locale.cc && ./locale
Constructed locale "C"
This locale is the global locale.
This locale is the C locale.
$ g++ -Wall -o locale locale.cc && ./locale POSIX
Constructed locale "POSIX"
This locale is the global locale.
This locale is the C locale.
$ g++ -Wall -o locale locale.cc && ./locale en_CA.UTF-8
Constructed locale "en_CA.UTF-8"
This locale is not the global locale.
This locale is not the C locale.
$ g++ -Wall -o locale locale.cc && ./locale garbage
Can't construct locale "garbage": locale::facet::_S_create_c_locale name not valid
Note how "C" and "POSIX" are two names for the same locale with gcc on glibc.
Here's the same program run on a mac:
$ ./locale
Constructed locale "C"
This locale is the global locale.
This locale is the C locale.
$ ./locale POSIX
Constructed locale "POSIX"
This locale is not the global locale.
This locale is not the C locale.
$ ./locale en_CA.UTF-8
Constructed locale "en_CA.UTF-8"
This locale is not the global locale.
This locale is not the C locale.
$ ./locale garbage
Can't construct locale "garbage": collate_byname<char>::collate_byname failed to construct for garbage
$ clang++ -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Here, "C" and "POSIX" are different, but "garbage" still fails.
Emscripten is currently accepting any string, it seems, and it is also treating "C" and "POSIX" as distinct:
$ em++ -Wall -o locale.js locale.cc && node ./locale.js
Constructed locale "C"
This locale is the global locale.
This locale is the C locale.
$ em++ -Wall -o locale.js locale.cc && node ./locale.js POSIX
Constructed locale "POSIX"
This locale is not the global locale.
This locale is not the C locale.
$ em++ -Wall -o locale.js locale.cc && node ./locale.js en_CA.UTF-8
Constructed locale "en_CA.UTF-8"
This locale is not the global locale.
This locale is not the C locale.
$ em++ -Wall -o locale.js locale.cc && node ./locale.js garbage
Constructed locale "garbage"
This locale is not the global locale.
This locale is not the C locale.
I think the correct behaviour would to work as the C setlocale() function does, failing when the argument names an unsupported locale. However, I can't find any information on whether "C" and "POSIX" should be aliases to std::locale just like they are for setlocale(), and Linux and Mac seem to disagree. :(
Test program:
#include <locale>
#include <iostream>
#include <stdexcept>
int
main(const int argc, const char * const * const argv)
{
const char * const name = argc > 1 ? argv[1] : "C";
try {
const std::locale locale(name);
std::cout
<< "Constructed locale \"" << name << "\"\n"
<< "This locale is "
<< (locale == std::locale::global(locale) ? "" : "not ")
<< "the global locale.\n"
<< "This locale is " << (locale == std::locale::classic() ? "" : "not ")
<< "the C locale." << std::endl;
} catch(const std::runtime_error &ex) {
std::cout
<< "Can't construct locale \"" << name << "\": " << ex.what()
<< std::endl;
return 1;
} catch(...) {
std::cout
<< "FAIL: Unexpected exception constructing locale \"" << name << '\"'
<< std::endl;
return 127;
}
}
$ em++ -v; em++ --version
emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) 1.22.0
clang version 3.3 (https://github.com/kripken/emscripten-fastcomp-clang 545ce52e3e149a1a1ae65b2b348310f7e0d0a2de) (https://github.com/kripken/emscripten-fastcomp 145e2109a41024cf40fd53bb29e51f3a12c025b9)
Target: x86_64-unknown-linux-gnu
Thread model: posix
INFO root: (Emscripten: Running sanity checks)
emcc (Emscripten GCC-like replacement) 1.22.0 (commit 8ee23fb4249f40dc31c75bd39ce3d765745d5bf1)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This is the C++ version of Issue #2630. I didn't realize it was a distinct issue yesterday. Sorry.
The std::locale() constructor taking a locale name must fail when the locale isn't supported. Here's the behaviour I would expect with gcc when the "en_CA.UTF-8" locale is supported in addition to "C":
Note how "C" and "POSIX" are two names for the same locale with gcc on glibc.
Here's the same program run on a mac:
Here, "C" and "POSIX" are different, but "garbage" still fails.
Emscripten is currently accepting any string, it seems, and it is also treating "C" and "POSIX" as distinct:
I think the correct behaviour would to work as the C setlocale() function does, failing when the argument names an unsupported locale. However, I can't find any information on whether "C" and "POSIX" should be aliases to std::locale just like they are for setlocale(), and Linux and Mac seem to disagree. :(
Test program: