Skip to content

Horrible failure mode for 'load_file' functions in test examples #274

@jwakely

Description

@jwakely

if(is.bad()) return;
s.reserve(static_cast<std::string::size_type>(is.rdbuf()->in_avail()));

Testing is.bad() is almost certainly wrong, that will only be true if the fstream has encountered some I/O error or lost integrity somehow. Maybe you meant to test is.fail() instead? Or just !is which is !is.good() which is almost always what you should actually be testing?

Otherwise, when the fstream is not open (e.g. because argv[1] refers to a non-existent file) the fstream is not open, so is.fail() is true, and is.good() is false, but is.bad() is false because no I/O error has been encountered. The file just isn't open, that's "fail" not "bad". So the condition is false and you go to the next line, where in_avail() returns -1ul and you try to reserve an impossibly large number, so the program exits with:

Processing file /home/boost.kCe5Net2fE/BUILD/boost-1.90.0-build/boost_1_90_0/libs/regex/example/../include/boost/regex/v5/regex_iterator.hpp
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

This is extremely unfriendly. It seems like it would be much better to do something like:

void load_file(std::string& s, std::istream& is)
{
   s.erase();
   if(!is) throw std::runtime_error("Cannot read file");
   s.reserve(static_cast<std::string::size_type>(is.rdbuf()->in_avail()));

The load_file function is duplicated in loads of the files under examples/snippets

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions