2012-06-25 19 views
8

Il seguente codice funziona bene su Linux, ma genera un'eccezione su OS X 10.7:Impostazione locali su OS X si blocca

#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; 
} 

L'uscita su OS X è:

locale::facet::_S_create_c_locale nome non valida

Tuttavia, lo standard dice esplicitamente che

Il set di valori di argomenti stringa validi è "C", "" e qualsiasi valore definito dall'implementazione.

Quindi qualsiasi cosa causi il comportamento sopra violare lo standard.

Il compilatore utilizzato è clang ++ 3.1 (tag/Apple/clang-318.0.58); Ho anche provato con GCC 4.7, installato tramite Homebrew, con lo stesso risultato.

Possono altre persone convalidare questo problema? Cosa lo causa? Sto facendo qualcosa di sbagliato? Si tratta di un bug in OS X?

(Forse questo relates to another xlocale problem ma gli errori sono in realtà completamente diversa.)

+0

Penso che questo sia (quasi) un duplicato di [questa domanda] (http://stackoverflow.com/questions/1745045/stdlocale-breakage-on-macos-10-6-with-lang-en-us- utf-8) ... –

+0

@EitanT Buona scoperta, è (un * esatto * duplicato)! Grazie. –

+0

Non penso che tu stia usando xlocale. Credo che tu sia un problema con libstdC++, che usa una diversa libreria di supporto locale (che apparentemente non è supportata su OS X, come la domanda EitanT collega agli stati). Penso che se passi a libC++ il tuo programma funzionerà. Sebbene come dettagli della mia domanda, ci sono problemi con alcune impostazioni locali in libC++, a causa di bug in xlocale. – bames53

risposta

2

Non credo che si sta utilizzando xlocale. Credo che il tuo problema sia con libstdC++, che usa una diversa libreria di supporto locale che non è supportata su OS X, come la domanda che EitanT collega agli stati.

Se si passa a libC++, il programma funzionerà.

0

Il poster sopra corretto ... il problema è con libstdC++. Volevo aggiungere la mia risposta perché non è semplice come ottenere OS X da collegare a libC++ e mi ci è voluto più di un'ora per capirlo.

Invocare il compilatore/linker per g++ -libstd=libc++ o clang++ -libstd=libc++ o l'alias c++ -libstd=libc++ saranno tutti fallire.

La soluzione per compilare semplici programmi dalla riga di comando anziché scherzi con l'overhead aggiunto di Xcode è di consentire Xcode per gestire il collegamento con il comando xcrun clang++ -stdlib=libc++

xcrun permette Xcode di gestire la catena utensile, costruire un eseguibile di successo dove cout.imbue(locale(foo)) funzionerà correttamente.

+3

In realtà puoi usare libC++ bene con 'clang ++' quando fai quanto segue: 'export CXX =" clang ++ - $ cxxver -stdlib = libC++ "' e 'export CXXFLAGS =" - nostdinC++ -isystem/usr/local/lib/llvm - $ cxxver/include/C++/v1 "' (per un appropriato '$ cxxver'). Non * fare affidamento su Xcode in nessuna parte del processo, in particolare dopo aver installato una versione più recente di Clang tramite Homebrew. –

+0

Konrad, apprezzo l'aiuto, ma puoi aiutare un principiante e spiegare un po 'di più cosa fanno questi comandi? – user3176017

+2

I comandi 'export' impostano le variabili di ambiente nel terminale. [Familiarizza con le variabili 'CXX' e' CXXFLAGS'] (http://www.gnu.org/software/make/manual/make.html), sono piuttosto importanti per lo sviluppo di C++ su Unix. Ora, le opzioni impostate con queste variabili sono '-nostdinC++', che disabilita l'utilizzo dell'implementazione predefinita della libreria standard. '-libC++' dice a clang di usare libC++ invece del default (libstdC++), e '-system ...' dice a clang dove trovarlo. –