Difference in stringstream behavior for void* type using libc++ and libstdc++

后端 未结 2 624
伪装坚强ぢ
伪装坚强ぢ 2021-01-12 08:10

The following test program returns different results depending on whether I\'m using libc++ or libstdc++.

#include 
#include 
         


        
相关标签:
2条回答
  • 2021-01-12 08:21

    This has been fixed in libc++ as of revision 209305.

    0 讨论(0)
  • 2021-01-12 08:33

    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;
    }
    
    0 讨论(0)
提交回复
热议问题