#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)