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


the following test program returns different results depending on whether i'm using libc++ or libstdc++.

#include <sstream> #include <iostream>  int main() {     int = 0;     void* optr = &a;     void* iptr;      std::stringstream ss;     ss << optr;     std::cout << ss.str() << '\n';      ss >> iptr;     std::cout << iptr << '\n';      return 0; } 

i'm using following version of clang xcode 5 on osx 10.9.2

$ xcrun clang++ --version               apple llvm version 5.0 (clang-500.2.79) (based on llvm 3.3svn) target: x86_64-apple-darwin13.1.0 thread model: posix 

here's output of test when built libstdc++ , libc++

$ xcrun clang++ test.cpp  <-- libstdc++ version              $ ./a.out 0x7fff5ec723e8 0x7fff5ec723e8 $ xcrun clang++ test.cpp -stdlib=libc++  <-- libc++ version $ ./a.out 0x7fff5205125c 0x7fff5 

is bug in libc++ implementation of stringstream? usage of void* stringstream valid c++?

thanks!

yes! it's bug in libc++, in implementation of __sscanf_l (some scanf lookalike should take locales consideration). libstdc++ implemementation 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;     (; __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 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 hex formatted input.   __io.flags(__fmt);    __v = reinterpret_cast<void*>(__ul);   return __beg; } 

Comments

Popular posts from this blog

python - Healpy: From Data to Healpix map -

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -