Topic: basic_ifstream<>::open()


Author: david@kai.com (David C. Nelson)
Date: 1998/06/05
Raw View
Now that we've talked round the problem back into the inheritance
tree, lets get back to the specific derived class, basic_ifstream. It
derives from basic_istream and has its own file based stream buffer.
My original inquiry related to its open() and close() methods. These
methods are not available in any other stream class.

I just checked a copy of the cfront library source for fstream, I see
that upon success of open, close, attach and setbuf it did a clear(0).
So was it intended that this bit of functionality was removed from the
fstream family?

We can discus the philosophy of the design until we're blue in the
face, but at some point we have to own up to the question, did we
intend to break the user's code?

--
#include <std/disclaimer.h>                 Kuck and Associates
David Nelson (david@kai.com)                1906 Fox Drive
http://www.kai.com/C_plus_plus/_index.html  Champaign, IL   61820
KAI C++ - Cross Platform C++ Compiler       (217) 356-2288 ext 36
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: david@kai.com (David C. Nelson)
Date: 1998/06/03
Raw View
It seems to me that open in basic_ifstream<> and basic_ofstream<>
should set the state to goodbit. But I cannot find text in the draft
to say this is so. Consider the case where after reading all of an
ifstream (eofbit set), that it is close()'d and then a new file is
successfully open()'d. Clearly the eofbit should not be set as we have
just opened a new file. The draft(Sec 27.8.1.7) is clear that the
failbit should be set if the filebuf's open failed, but what about if
it succeeds?  How much of the istream should be reset? It is obvious
to me that the state needs to be cleared, but what about the
formatting flags?

--
#include <std/disclaimer.h>                 Kuck and Associates
David Nelson (david@kai.com)                1906 Fox Drive
http://www.kai.com/C_plus_plus/_index.html  Champaign, IL   61820
KAI C++ - Cross Platform C++ Compiler       (217) 356-2288 ext 36


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/06/04
Raw View
David C. Nelson<david@kai.com> wrote:
>It seems to me that open in basic_ifstream<> and basic_ofstream<>
>should set the state to goodbit. But I cannot find text in the draft
>to say this is so.

The philosophy for iostream error state seems to be: set on error,
don't touch otherwise.  This means your own code has full control
of when error state gets cleared.

This policy appears to be inherited from the UNIX errno behavior:
successful system calls don't touch errno.  I don't know if it is a
good policy, but the iostream library seems to be consistent about it.
Perhaps this was intended to help error reports propagate to the
next point when somebody finally gets around to checking for them.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: david@kai.com (David C. Nelson)
Date: 1998/06/04
Raw View
> The philosophy for iostream error state seems to be: set on error,
> don't touch otherwise.  This means your own code has full control
> of when error state gets cleared.

But what about the eof condition? This is more of a status than an
error condition. Given that a file was just successfully opened, it
seems incorrect to report that the file is at eof.

> This policy appears to be inherited from the UNIX errno behavior:
> successful system calls don't touch errno.  I don't know if it is a
> good policy, but the iostream library seems to be consistent about it.
> Perhaps this was intended to help error reports propagate to the
> next point when somebody finally gets around to checking for them.

OK, I'll grant you that goodbit is perhaps too big of a hammer. But,
the EOF condition of a stdio FILE is reset if the FILE is closed and a
new one opened.  With ifstream this does not seem to be the case.

Also, with C's errno, most everything returns an error flag and errno
let you know what error occurred. For the most part, you could ignore
errno and just check the return values. When you detected an error,
you could use the current value of errno to tell what went
wrong. Often one would continue to use the the FILE. The success of
operations is generally testable without errno being reset.  On the
other hand, the stream is in a generally unusable state until you
clear the status flag. You have to reset the error condition to be
able to detect the success/failure of ifstream's close() and
open(). This seems to be the price to pay for the convenience.

--
#include <std/disclaimer.h>                 Kuck and Associates
David Nelson (david@kai.com)                1906 Fox Drive
http://www.kai.com/C_plus_plus/_index.html  Champaign, IL   61820
KAI C++ - Cross Platform C++ Compiler       (217) 356-2288 ext 36




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/06/05
Raw View
David C. Nelson<david@kai.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>> The philosophy for iostream error state seems to be: set on error,
>> don't touch otherwise.  This means your own code has full control
>> of when error state gets cleared.
>
>But what about the eof condition? This is more of a status than an
>error condition. Given that a file was just successfully opened, it
>seems incorrect to report that the file is at eof.

This is a matter of how you interpret the flag.  It *should* be
interpreted as "this istream has noticed an EOF from its streambuf
since the flag was last cleared".   After all, for some streambufs
you don't even have to re-open; just wait.  You might have an
istream and an ostream attached to the same stringstreambuf.
Write more characters on it, and the istream can read them, eof
or no eof.

istream and ostream deliberately have no "state" related to the
streambuf aside from these flags, so they are necessarily just
latched states of events in the past, rather than "status".
If it were otherwise, the stream would have to clear it
frequently, creating overhead.

To describe it another way, istream and ostream are scanning and
formatting services (respectively), like scanf and printf.
(It's unfortunate that they acquired seek and flush members
to confuse matters.)  The flags are intended to report the
condition of the last scan or format, not the state of the
underlying channel, which is known only to the streambuf.

>Also, with C's errno, most everything returns an error flag and errno
>let you know what error occurred. For the most part, you could ignore
>errno and just check the return values. When you detected an error,
>you could use the current value of errno to tell what went
>wrong. Often one would continue to use the the FILE. The success of
>operations is generally testable without errno being reset.  On the
>other hand, the stream is in a generally unusable state until you
>clear the status flag. You have to reset the error condition to be
>able to detect the success/failure of ifstream's close() and

Interestingly, the eof bit is closer to errno than you may realize.
ios::fail() doesn't test it, and it is not always set when you are at
end of file (i.e. if it's off that doesn't mean a read will succeed)
so the only reason to check it is to determine why some other detected
problem occurred.

Generally, it's only set if EOF was the reason for a failure, as
opposed to a bad format.  Hence, the canonical sequence is:

  str.clear();
  if (!(str >> date)) {
    if (!str.eof()) ...  // hit an unexpected character
    else            ...  // ran out of characters, no telling why
  }

It's not an error for a streambuf to yield a sequence like this:

  1 2 3 EOF 4 5 6 EOF

In this case

  str >> i >> j;

would yield i=123 and j=456, and str.rdstate() would be ios_base::eof
(so str.fail() would be false).

To check the condition of the streambuf itself, you can call its
member functions.  At minimum, you can call str.rdbuf()->sgetc()
which will return EOF if it's (still) at EOF.  If you know more
about the streambuf's actual type (e.g. filebuf), you can call
member functions specific to its type to get more information
about it; E.g.

  if (dynamic_cast<Monkeybuf&>(*str.rdbuf()).monkey_died()) ...

The lesson here is: don't be afraid of streambufs
(and, as usual, always mount a scratch monkey).

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]