Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange exception from boost::lexical_cast with boost::filesystem

Tags:

c++

boost

On RHEL7.4, boost 1.53,

#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;

int main() {
    const string& s1 = "1024";
    cout << "test1:" << lexical_cast<unsigned int>(s1) << endl;

    filesystem::path p("1024");
    cout << "test2:" << lexical_cast<unsigned int>(p.filename().string()) << endl;

    const string& s2 = p.filename().string();
    cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;

    return 0;
}

This code gives:

test1:1024
test2:1024
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >'
  what():  bad lexical cast: source type value could not be interpreted as target
zsh: abort      ./a.out

Maybe this is a lexical_cast's bug but someones knows why test3 fails? Especially, I can't understand different between test1 and 3.

like image 516
Hiroshi Araki Avatar asked Dec 11 '25 18:12

Hiroshi Araki


1 Answers

This line creates a dangling reference:

const string& s2 = p.filename().string();

That's because on POSIX systems, path::filename() returns a reference to a member(!!!). Therefore, no lifetime extension occurs, as would have been if it had returned a temporary.

Now, because filename() returns a temporary path() the reference is no longer valid. Your program invokes Undefined Behaviour.

I'd suggest a fix like:

p = p.filename();
const string& s2 = p.string();
cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;

Or

p = p.filename();
cout << "test3:" << lexical_cast<unsigned int>(p.string()) << endl;

Or even

cout << "test3:" << lexical_cast<unsigned int>(p.filename().string()) << endl;

Best of all would be to keep things simple:

std::string const s2 = p.filename().string();
cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;
like image 104
sehe Avatar answered Dec 14 '25 09:12

sehe