Skip to content

std::locale constructor accepts unknown locale names instead of failing #2636

Description

@b-spencer

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions