|
Boost : |
Subject: Re: [boost] [lexical_cast] locale dependent result?
From: Artyom (artyomtnk_at_[hidden])
Date: 2011-03-02 11:09:34
> > If you want to do casting without locale context (which is desirable)
> >
> > std::ostringstream ss;
> > ss.imbue(std::locale::classic()); // C locale
> > ss << 65535;
> > return ss.str();
>
> Thanks! So std::locale::classic effectively means 'turn locale awareness
> off'?
It installs default so called "C" or "POSIX" locale that is what you need.
>
> > Unfortunately this problem is very common and causes
> > many bugs, especially in C with setlocale and printf.
>
> I can imagine! It's so subtle and unexpected. In fact, I used
> lexical_cast precisely because I thought it wouldn't do anything funky with
> the conversion.
>
It is not about lexical cast only it is about anything that uses iostream
and *printf/*scanf/ato* and many other library functions.
I recently seen how C (and C++) SQL libraries being broken because
of global locale.
> At least that's how I interpreted the documentation: "For more involved
> conversions, such as where precision or formatting need tighter control
> than is offered by the default behavior of lexical_cast, the conventional
> stringstream approach is recommended."
>
The best is unfortunatly is avoid installing std::locale global using standard
C++ localization, in fact because of this problem in Boost.Locale the default is
to use C locale. i.e.
ss << 65536;
ss.str() == "65536";
And if you need localized numbers:
ss << boost::locale::as::number
ss.str() == "65,536"
Because too many libraries become broken by this "feature" as
std::locale::global(std::locale("de_DE.UTF-8"));
std::ostringstream ss;
ss << 12345.345;
Would create "12.345,345" and
printf("%f\n",12345.345);
Would generate
12345,345 // <-- note "," and not "."
So imagine how many libraries and programs do not
work in such setups :-)
Artyom
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk