#7704 closed Bugs (fixed)
lexical_cast to filesystem::path fails for string::length > 22
Reported by: | Owned by: | Antony Polukhin | |
---|---|---|---|
Milestone: | Boost 1.54.0 | Component: | lexical_cast |
Version: | Boost 1.52.0 | Severity: | Problem |
Keywords: | Cc: |
Description
When building with clang on Darwin using -stdlib=libc++
, a lexical_cast
to a filesystem::path
will fail if the input string is longer than 22 elements.
Consider this test program:
#include <boost/lexical_cast.hpp> #include <boost/filesystem/path.hpp> int main() { try { boost::filesystem::path p; std::string s1 = "aaaaaaaaaaaaaaaaaaaaaaa"; p = boost::lexical_cast<boost::filesystem::path>(s1); } catch (std::exception & ex) { std::cerr << ex.what() << std::endl; return EXIT_FAILURE; } }
…compiled thusly:
clang++ -stdlib=libc++ -I /Users/bradenmcdaniel/Source/boost_1_52_0 -L /Users/bradenmcdaniel/Source/boost_1_52_0/stage/lib -lboost_filesystem -lboost_system -o lexical-cast-path lexical_cast_path.cpp
When run, it produces this output:
$ ./lexical-cast-path bad lexical cast: source type value could not be interpreted as target
If the length of s1
is reduced by 1 (from 23 to 22), the test program will succeed.
Change History (12)
comment:1 by , 10 years ago
Component: | None → lexical_cast |
---|---|
Owner: | set to |
comment:2 by , 10 years ago
comment:3 by , 10 years ago
That's consistent with what I've seen: I was not able to reproduce the problem when building without the -stdlib=libc++
flag. Unfortunately, the version of GNU libstdc++ available on Darwin is rather dated and thus not perceived as a path forward for new C++ development.
Here is a backtrace from the throw point:
#0 0x00007fff8457254d in __cxa_throw () #1 0x000000010000658c in boost::throw_exception<boost::bad_lexical_cast> (e=@0x7fff5fbff9a0) at throw_exception.hpp:66 #2 0x0000000100006249 in boost::detail::lexical_cast_do_cast<boost::filesystem::path, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::lexical_cast_impl (arg=@0x7fff5fbffaa0) at lexical_cast.hpp:2141 #3 0x0000000100005b7c in boost::lexical_cast<boost::filesystem::path, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > (arg=@0x7fff5fbffaa0) at lexical_cast.hpp:2300 #4 0x0000000100005162 in main () at lexical_cast_path.cpp:10
If you'd like me to try to get one from some other point in the code, let me know.
follow-up: 5 comment:4 by , 10 years ago
Try this code:
#include <sstream> #include <boost/filesystem/path.hpp> int main() { boost::filesystem::path p; std::istringstream s1("aaaaaaaaaaaaaaaaaaaaaaa"); s1 >> p; if (s1.get() != std::char_traits<char>::eof()) return EXIT_FAILURE; return 0; }
If it exits with EXIT_FAILURE
, then it is a bug in libc++
comment:6 by , 10 years ago
Please, try this one:
#include <sstream> #include <boost/filesystem/path.hpp> #include <boost/lexical_cast.hpp> template< class BufferType > class stl_buf_unlocker: public BufferType{ public: typedef BufferType base_class; using base_class::pptr; using base_class::pbase; using base_class::setg; using base_class::setp; }; typedef stl_buf_unlocker<std::basic_stringbuf<char> > unlocked_but_t; int main() { char data[] = "aaaaaaaaaaaaaaaaaaaaaaa"; char* start = data; char* finish = start + sizeof(data); std::basic_istringstream<char> stream; static_cast<unlocked_but_t*>(stream.rdbuf())->setg(start, start, finish); stream.unsetf(std::ios::skipws); std::string output; // boost::filesystem::path output; const bool b1 = (stream >> output); const bool b2 = (stream.get() == std::char_traits<char>::eof()); BOOST_ASSERT(b1); BOOST_ASSERT(b2); return 0; }
If it does not trigger asserts, then comment std::string output;
and uncomment boost::filesystem::path output;
and try it once more.
comment:8 by , 10 years ago
comment:9 by , 10 years ago
comment:11 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [83689]) Merge from trunk:
comment:12 by , 10 years ago
Milestone: | To Be Determined → Boost 1.54.0 |
---|
Could not reproduce it on clang version 3.0-6ubuntu3 with default stl library.
It looks more like a libc++ bug, but I`m not sure.
Could you attach a backtrace? ( Have not found a .deb pakage for libc++ and don`t have enough time to install libc++ from sources)