I’ve looked at the standard and didn’t see an obvious answer.
suppose i’ve done this:
std::istream_iterator<char> is(file);
while(is != std::istream_iterator<char>()) {
++is;
}
now is is at the end of the stream and is equal to std::istream_iterator<char>(). What happens if I increment it one more time? Is it still equal to std::istream_iterator<char>()? or os the result undefined?
The standard explicitly states that *is is undefined behavior if is is at the end of the stream. But I haven’t seen anything regarding iterating beyond the end of the stream…
EDIT:
I ask because I stumbled across some code which does something like this:
// skip 2 input chars
++is;
++is;
if(is != std::istream_iterator<char>()) {
// continue using is and do some work...but what if the first
// increment made it EOS? is this check valid?
}
Table 72 in C++03 about input iterator requirements says that the pre-condition of
++ris thatris de-referenceable. The same pre-conditions holds forr++.Now,
24.5.1/1says aboutistream_iteratorIn conclusion, the effects of
operator++on an end-of-stream iterator are undefined.Table 72 in C++03 about input iterator requirements says that the pre-condition of
++ris thatris de-referenceable. The same pre-conditions holds forr++.Now,
24.5.1/1says aboutistream_iteratorIn conclusion, the effects of
operator++on an end-of-stream iterator are undefined.Note that I think this conclusion makes behavior undefined only when you write or use an algorithm taking input iterators which exhibits that behavior, and then pass an istream iterator. From only using the istream iterator itself explicitly, without treating it as an input iterator and relying on its invariants, then i think the conclusion above isn’t quite right (we may have a class that doesn’t require that
ris dereferenceable, for example).But looking at how istream iterator is described, an invocation of
operator++after reaching the end of stream value results in undefined behavior either.operator==for it is defined as being equivalent toWhere
in_streamis a pointer to the stream iterated over – and exposed into the Standard text for defining behavior and semantics “exposition only”. Now, the only implementation i can think of that makes this work, is using an end-of-stream iterator that stores as stream pointer a null pointer. Butoperator++is defined as doing something having the effect of the followingNow, if you enter the end-of-stream state, and we would set
in_streamto a null pointer, then surely the effect of that would be undefined behavior.So even if you use the istream iterator alone, there doesn’t seem to be any guarantee that you may increment past the end-of-stream value.