Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost filesystem::path constructor std::length_error

i am trying to iterate over a directory using Boost.Filesystem library.

The problem is that when i try to instantiate a path object, i get an std::length_error with the message "string too long" with strings of any length, even for example "pippo".

I have already tried all of these:

string s = "pippo";

path p(s);
path p(s.begin(), s.end());
path p(s.c_str());
path p("pippo");

I am on windows 7 with boost precompiled version 1.47 for vc++10.

Thank you in advance, Luca

EDIT

this is the boost code executed (path.hpp line 129)

template <class Source>
path(Source const& source,
  typename boost::enable_if<path_traits::is_pathable<
    typename boost::decay<Source>::type> >::type* =0)
{
  path_traits::dispatch(source, m_pathname, codecvt());
}

and the error is thrown from (path_traits.hpp line 174)

template <class U> inline
void dispatch(const std::string& c, U& to, const codecvt_type& cvt)
{
  if (c.size())
  convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
}

the function that throws is "convert". From the debugger i saw that both

&*c.begin()  

and

&*c.begin() + c.size()

are correctly executed

like image 712
Luca Piccinelli Avatar asked Nov 04 '22 09:11

Luca Piccinelli


1 Answers

You mentioned that Boost is pre-compiled for VC++10, but you didn't say which compiler YOU are using. If you are using Visual C++ Express you need to compile it yourself.

But, since I'm about to use boost::filesystem, I thought I'd investigate to learn a bit myself.

Firstly, you should almost never be putting an entire Boost namespace into your plain namespace wherever possible (especially if you are doing so with std!). Posting code like this makes it look like you are "using namespace" too much. If you don't want to type boost::filesystem everywhere, do this:

namespace fs = boost::filesystem;
fs::path p(whatever);

or

using boost::filesystem::path;
using std::string;
string foo("Hello!");
path p(foo);

Including Boost namespaces in your local namespace like you seem to can have disastrous consequences (or work fine, it's the luck of the draw). As you noticed, the function call that kills it is convert() - is there perhaps another convert() somewhere that is superseding it?

Next, you should enable automatic linking (for this library). The official Boost documentation says to use automatic linking. The Boost people are very smart (perhaps too smart - working with the time libraries is a pain...) It works well for Visual Studio 2010.

If that doesn't fix it, your precompiled Boost is using a different CRT (since the convert function appears to be in the Boost library). This can happen for many reasons, for instance, the VS2k10 service pack may be installed on your source/not on yours, etc.

The ultimate solution is to compile Boost yourself. It's very, very easy on Windows: download Boost sources, and extract to any directory. Then open a command prompt (start->run cmd.exe) and do:

cd\
cd "boost root directory"
boostrap
.\b2

Then just wait about 45 minutes on a Core 2 Duo 2.5GHz. It will generate the Boost libraries with the correct CRT. If you still have problems then, then there is something deeper wrong with your build system, such as linking against a static Boost library while using DLL CRT (you should link DLL Boost with DLL CRT).

like image 189
std''OrgnlDave Avatar answered Nov 09 '22 05:11

std''OrgnlDave