This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Funniness with operator>> (istream&, string&)



> When i run this test, it does not properly sense the EOF condition,
> but instead goes into an infinite loop:

Yeah. There was some discussion of this change to istream::sentry here,
read the whole thread.

http://sourceware.cygnus.com/ml/libstdc++/2000-q1/msg00004.html

You'll need to specifially test for istream.good(), not the boolean
operator, which only tests for fail().

> The sentry class used to set failbit as well on eof.
> 
> So i was set to write this up as a bug report.
> But after studying the C++ standard for a while, i do not find support
> for the assertion that this is a bug; in fact, the infinite loop seems
> to be the specified behavior.

(Welcome to my world of pain?)

Look at the defect comments surrounding this change:

#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//195.  Should basic_istream::sentry's constructor ever set eofbit? 
	      else
		__in.setstate(ios_base::eofbit);
#endif

This was initally brought up because istream::sentry didn't explicitly set
eofbit (although it was implied). The proposed change set eofbit |
failbit, which then introduced an inconsistency between hitting eof as one
is clearing whitespace in the sentry ctor (which would then set
eofbit|failbit and cause operator bool() to fail) versus hitting eof as
one is doing formatted/unformatted extraction (which would then set just
eofbit, allowing operator bool() to pass).

perhaps what really should be done is have

bool basic_ios::operator!()
basic_ios::void*() const

work with good() instead of fail().


This issue was brought up with the library working group. It seems to have
stalled though, so I don't know the current status.

I would like to make the setting of failbit consistent. I believe the CVS
sources reflect the most consistent behavior.

> If i look at the description of operator>> (istream&, string)
> (21.3.7.9), i don't see anything that tells me that that failbit _should_
> be set in this case.  If i compare this with the description of similar
> functions -- for example getline<charT> (istream&, string&, charT) 
> (21.3.7.9) or operator>> (istream&, charT*) (27.6.1.2.3) or
> istream::get (char_type*, streamsize, char_type) (26.6.1.3) -- i see
> that the descriptions of those functions all include a statement to the
> effect that `If the functions extracts no characters, it calls
> setstate(failbit)'.  However, in the case of operator>> (istream&, string&),
> this requirement is conspicuously absent.

This makes sense. I believe it should set failbit here too. This is a
separate issue from istream::sentry::sentry() setting failbit though.

> So, i'm wondering, is this an error in the standard, or is this
> a deliberate decision? 

another mistake.

> I don't see any mention of this in the
> library issues list.  On the other hand, i can't think of any reason
> why the behavior specified in the standard (i.e., not setting failbit
> in the case where no characters were extracted) would be desireable.
> In fact, i can think of several reasons why it's not a good thing:
> 
>  - The semantics of failbit are described as including (table 85)
>    `an input operation failed to read the expected characters'.
>    This is exactly what's happening in this case -- but failbit
>    is not getting set.

right

> 
>  - One could perhaps argue that the intended semantics of
>    operator>> (istream&, string&) at EOF is to read
>    an empty string and return success.  However, the specification
>    of this operator does not ensure the first part of this: if no characters
>    are extracted, the string argument to the operator is untouched.
>    So, old data will be seen in the string, rather than the empty string.

I think this is not intuitive.

>  - One might say that for using this operator, one needs to use
>    good() or !eof() on the stream, rather than testing failbit.
>    But that means that it is impossible to use istream_iterator<stream>,
>    since the end-of-sequence testing for an istream_iterator is
>    specified as being a test of failbit.

see above. . 

-benjamin


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]