8

The following code works fine on Linux but throws an exception on OS X 10.7:

#include <iostream>
#include <locale>
#include <stdexcept>

int main() try {
    std::locale::global(std::locale(""));
    std::cout << "Using locale: " << std::locale().name() << "\n";
}
catch (std::runtime_error const& e) {
    std::cout << e.what() << "\n";
    return 1;
}

The output on OS X is:

locale::facet::_S_create_c_locale name not valid

However, the standard explicitly says that

The set of valid string argument values is "C", "", and any implementation-defined values.

So whatever causes the behaviour above is violating the standard.

The compiler used is clang++ 3.1 (tags/Apple/clang-318.0.58); I’ve also tried it with GCC 4.7, installed via Homebrew, with the same result.

Can other people validate this problem? What causes it? Am I doing anything wrong? Is this a bug in OS X?

(Maybe this relates to another xlocale problem but the errors are actually completely different.)

Community
  • 1
  • 1
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • I think this is (almost) a duplicate of [this question](http://stackoverflow.com/questions/1745045/stdlocale-breakage-on-macos-10-6-with-lang-en-us-utf-8)... – Eitan T Jun 25 '12 at 14:30
  • @EitanT Good find, it is (an *exact* duplicate)! Thanks. – Konrad Rudolph Jun 25 '12 at 14:33
  • I don't think you're using xlocale. I believe that you're problem is with libstdc++, which uses a different locale support library (which is apparently not supported on OS X, as the question EitanT links to states). I think if you switch to libc++ your program will work. Although as my question details, there are problems with some locales in libc++, because of bugs in xlocale. – bames53 Jun 25 '12 at 14:56
  • @bames53 Awesome, mind writing this in an answer? Then I can upvote & accept. You’re right that this comes with its own problems (locale name when printed is empty) but at least it now appears to be using UTF-8 when actually used on some input. – Konrad Rudolph Jun 25 '12 at 15:05

2 Answers2

2

I don't think you're using xlocale. I believe that your problem is with libstdc++, which uses a different locale support library that is not supported on OS X, as the question EitanT links to states.

If you switch to libc++ your program will work.

bames53
  • 86,085
  • 15
  • 179
  • 244
0

The poster above it correct...the problem is with libstdc++. I wanted to add my answer because it is not straightforward how to get OS X to link against libc++ and took me over an hour to figure out.

Invoking the compiler/linker by g++ -libstd=libc++ or by clang++ -libstd=libc++ or by the alias c++ -libstd=libc++ will all fail.

The solution for compiling simple programs from the command line instead of messing with the added overhead of Xcode is to allow Xcode to handle the linking by using the command xcrun clang++ -stdlib=libc++

xcrun allows Xcode to manage the tool chain and will build a successful executable where cout.imbue(locale(foo)) will successfully work.

user3176017
  • 103
  • 1
  • 10
  • 3
    Actually you can use libc++ just fine with `clang++` when doing the following: `export CXX="clang++-$cxxver -stdlib=libc++"` and `export CXXFLAGS="-nostdinc++ -isystem /usr/local/lib/llvm-$cxxver/include/c++/v1"` (for an appropriate `$cxxver`). I would *not* rely on Xcode at any part of the process – in particular after you’ve installed a newer version of Clang via Homebrew. – Konrad Rudolph Mar 11 '14 at 08:04
  • Konrad, I appreciate the help, but can you help out the a newbie and explain a little more what those commands do? – user3176017 Mar 15 '14 at 05:29
  • 2
    The `export` commands set environment variables in your terminal. [Familiarise yourself with the `CXX` and `CXXFLAGS` variables](http://www.gnu.org/software/make/manual/make.html), they are kind of important for C++ development on Unix. Now, the options set with these variables are `-nostdinc++`, which disables use of the default standard library implementation. `-libc++` tells clang to use libc++ instead of the default (libstdc++), and `-system …` tells clang where to find it. – Konrad Rudolph Mar 15 '14 at 10:33