Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ok to use std::getline() with a moved-from std::string?

Is it safe and well-defined for the second argument to std::getline(std::istream&, std::string&) to be an lvalue referring to a moved-from std::string, and, if so, is that string restored from its moved-from state, so methods such as pop_back() can be safely invoked?

Put more simply, does writing to a string with getline() have equivalent semantics to assigning to that string?

Or more concretely, is the following (somewhat contrived) snippet well-defined and correct?

std::ifstream f("foo.txt");

std::vector<std::string> lines;

for (std::string s; std::getline(f, s); lines.push_back(std::move(s)))
        if (!s.empty() && s.back() == '\r')
                s.pop_back();

Optimized (-march=native -O3) builds of this snippet with g++ and clang++ appear to work as expected, but that is of course no guarantee.

I'd like to know if this is relying only on well-defined behavior according to the semantics of getline() in the C++11 standard, or, if not, if it's well-defined by a later edition of the standard, or, if not, if it's at least explicitly defined by any/all of the major implementations (G++, Clang++, Visual C++, Intel C++ Compiler).

NB: This is not a duplicate of previous questions asking whether it's safe to assign to a moved-from object (yes, if it's a trivial or STL type) because getline() is not the assignment operator.

like image 965
Ray Hamel Avatar asked Oct 10 '17 18:10

Ray Hamel


1 Answers

Your code is safe, but only because you are checking if the getline successfully stored something in s. If the sentry internal to getline failed to initialize, then nothing would be assigned to s and it would be left in the valid-but-unspecified state. As long as getline succeeds in setting s to a known state, you're good.

And the very first thing getline does after successful sentry construction is set s to a zero size (a known state).

More details below in GManNickG's comment.

like image 156
Howard Hinnant Avatar answered Oct 08 '22 04:10

Howard Hinnant