Сбой std :: locale в MacOS 10.6 с LANG = en_US.UTF-8 - PullRequest
16 голосов
/ 17 ноября 2009

У меня есть приложение C ++, которое я портирую на MacOSX (в частности, 10.6). Приложение активно использует стандартную библиотеку C ++ и поддержку. Недавно в приложении произошел сбой, который я с трудом понимаю.

По сути, библиотека boost файловой системы выдает исключение времени выполнения при запуске программы. Немного отладив и прибегнув к поиску, я сократил вызывающий оскорбление вызов до следующей минимальной программы:

#include <locale>

int main ( int argc, char *argv [] ) {
    std::locale::global(std::locale(""));
    return 0;
}

Эта программа завершается сбоем, когда я запускаю ее через g ++ и выполняю полученную программу в среде, где задано LANG=en_US.UTF-8 (что на моем компьютере является частью сеанса bash по умолчанию при создании нового окна консоли). Очистка переменной среды (setenv LANG=) позволяет программе работать без проблем. Но я удивлен, что вижу эту поломку в конфигурации по умолчанию.

Мои вопросы:

  1. Это ожидаемое поведение для этого кода в MacOS 10.6?
  2. Каким будет правильный обходной путь? Я не могу переписать эту функцию, потому что версия используемых нами библиотек наддува выполняет этот оператор внутри себя как часть библиотеки файловой системы.

Для полноты картины следует указать, что программа, из которой был синтезирован этот код, аварийно завершает работу при запуске с помощью команды open (или из Finder), но не при запуске программы в режиме отладки Xcode.

edit Ошибка, указанная кодом выше в 10.6.1:

$ ./locale 
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
Abort trap

Ответы [ 5 ]

9 голосов
/ 17 ноября 2009

Хорошо, у меня нет ответа для вас, но у меня есть некоторые подсказки:

  • Это не ограничивается OS X 10.6. Я получаю тот же результат на 10,4 машины.
  • Я посмотрел на исходный код GCC для libstdc ++ и искал _S_create_c_locale. То, что я нашел, находится в строке 143 config / locale / generic / c_locale.cc . Там говорится: «В настоящее время универсальная модель поддерживает только язык« C »». Это не обещает. Фактически, если я сделаю LANG=C, ошибка времени выполнения исчезнет, ​​но любое другое значение для LANG, которое я пытаюсь вызвать, вызывает ту же ошибку, независимо от того, какие аргументы я предоставляю конструктору locale. (Я пробовал locale::classic(), "C", "" и по умолчанию). Это верно еще до GCC 4.0
  • На этой же странице есть ссылка на обсуждение списка рассылки libstdc ++ на эту тему. Я не знаю, насколько это плодотворно: я только проследил его немного вниз, и он очень быстро стал очень техническим.

Ничто из этого не говорит вам, почему языковой стандарт по умолчанию на 10.6 не будет работать с std::locale, но он предлагает обходной путь, который должен установить LANG=C перед запуском программы.

6 голосов
/ 28 марта 2015

Я столкнулся с этой проблемой совсем недавно на Ubuntu 14.04 LTS и на Raspberry Pi, на котором установлена ​​последняя версия Raspbian Wheezy.

Это не имеет ничего общего с OS X, а скорее с комбинацией G ++ и Boost (по крайней мере до V1.55) и настройками локали по умолчанию на определенных платформах. Есть проблемы с бустом, связанные с этой проблемой, см. билет # 4688 и билет # 5928 .

Мое "решение" было первым, чтобы выполнить дополнительную настройку локали, как предложено в этом сообщении AskUbuntu :

sudo locale-gen en_US en_US.UTF-8
sudo dpkg-reconfigure locales

Но затем я также должен был убедиться, что для переменной среды LC_ALL установлено значение LANG (желательно указать это в вашем .profile):

export LC_ALL=$LANG

В моем случае я использую локаль en_US.UTF-8.

Последнее замечание: OP сказал: «Эта программа не работает, когда я запускаю ее через g ++». Я понимаю, что этот поток был запущен в 2009 году, но сегодня абсолютно не нужно использовать GCC или G ++ на Mac , гораздо лучший пакет компиляторов LLVM / Clang доступен от Apple бесплатно, см. Домашняя страница XCode .

4 голосов
/ 28 апреля 2010

Ситуация все та же. Но некоторые функциональные возможности могут быть получены с помощью

setlocale( LC_ALL, "" );

Это дает вам кодировку UTF-8 на широких iostream с, но не форматирование денег, для моих двух точек данных.

locale::global( locale( "" ) );

должен быть эквивалентен, но он аварийно завершает работу, если впоследствии выполняется в той же программе.

3 голосов
/ 12 апреля 2010

У меня была такая же проблема, проверил LANG и LC_MESSAGES, и они не установлены, когда вы запускаете приложение через Finder, поэтому следующие строки сохранили день:

unset("LANG");
unset("LC_MESSAGES");
1 голос
/ 17 ноября 2009

Исключение _S_create_c_locale, по-видимому, указывает на некоторую неверную конфигурацию: убедитесь, что независимо от того, какая переменная окружения LC_ALL или LANG установлена, существует в выводе locale -a.

$ env LC_ALL=xx_YY ./test
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
Aborted
$ env LC_ALL=C ./test
$ echo $?
0

Но так как вы работаете в OS X, я не совсем уверен, как должна обрабатываться информация о локали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...