The following test program returns different results depending on whether I\'m using libc++ or libstdc++.
#include
#include
This has been fixed in libc++ as of revision 209305.
Yes! it's a bug in libc++, probably in the implementation of __sscanf_l
(some scanf
lookalike that should take locales into consideration). The libstdc++ implemementation is much simpler.
// libc++
template <class _CharT, class _InputIterator>
_InputIterator
num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
ios_base& __iob,
ios_base::iostate& __err,
void*& __v) const
{
// Stage 1
int __base = 16;
// Stage 2
char_type __atoms[26];
char_type __thousands_sep = 0;
string __grouping;
use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
__num_get_base::__src + 26, __atoms);
string __buf;
__buf.resize(__buf.capacity());
char* __a = &__buf[0];
char* __a_end = __a;
unsigned __g[__num_get_base::__num_get_buf_sz];
unsigned* __g_end = __g;
unsigned __dc = 0;
for (; __b != __e; ++__b)
{
if (__a_end == __a + __buf.size())
{
size_t __tmp = __buf.size();
__buf.resize(2*__buf.size());
__buf.resize(__buf.capacity());
__a = &__buf[0];
__a_end = __a + __tmp;
}
if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
__thousands_sep, __grouping,
__g, __g_end, __atoms))
break;
}
// Stage 3
__a[sizeof(__a)-1] = 0;
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
#else
if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1)
#endif
__err = ios_base::failbit;
// EOF checked
if (__b == __e)
__err |= ios_base::eofbit;
return __b;
}
versus
// libstdc++
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
do_get(iter_type __beg, iter_type __end, ios_base& __io,
ios_base::iostate& __err, void*& __v) const
{
// Prepare for hex formatted input.
typedef ios_base::fmtflags fmtflags;
const fmtflags __fmt = __io.flags();
__io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
typedef __gnu_cxx::__conditional_type<(sizeof(void*)
<= sizeof(unsigned long)),
unsigned long, unsigned long long>::__type _UIntPtrType;
_UIntPtrType __ul;
__beg = _M_extract_int(__beg, __end, __io, __err, __ul);
// Reset from hex formatted input.
__io.flags(__fmt);
__v = reinterpret_cast<void*>(__ul);
return __beg;
}