C++ Logo

std-discussion

Advanced search

Re: Setting badbit when outputting to an unopened fstream in eof state

From: Bo Persson <bo_at_[hidden]>
Date: Thu, 7 Nov 2019 13:04:13 +0100
On 2019-11-07 at 11:52, Gennaro Prota via Std-Discussion wrote:
> On Sun, Nov 3, 2019 at 9:23 PM Gennaro Prota <gennaro.prota_at_[hidden]> wrote:
>>
>> { Resending this, as it was apparently lost. }
>>
>> Hi,
>>
>> this program:
>>
>> #include <fstream>
>> #include <iostream>
>>
>> int
>> main()
>> {
>> std::fstream fs ;
>> fs.clear( std::ios_base::eofbit ) ;
>>
>> fs << "this isn't actually output" ;
>>
>> if ( ( fs.rdstate() & std::ios_base::badbit ) != 0 ) {
>> std::cout << "badbit set" << std::endl ;
>> }
>> }
>>
>> prints "badbit set" on Visual C++ 2015 and prints nothing with GCC or
>> Clang+libstdc++.
>>
>> Does the standard allow both behaviors?
>
> Since, differently from other questions, I didn't get any reply, I
> wonder: was this question off-topic? In fact, I didn't find any page
> explaining what is on topic and what is not for this list, so I just
> "went intuitively", so to speak. Sorry for that.
>

Not getting a reply could also mean that nobody knows the answer. :-)

Here's my take:

The requirements for formatted output
http://eel.is/c++draft/ostream.formatted.reqmts is:

"Each formatted output function begins execution by constructing an
object of class sentry. If this object returns true when converted to a
value of type bool, the function endeavors to generate the requested
output. If the generation fails, then the formatted output function does
setstate(ios_­base​::​failbit), which might throw an exception. If an
exception is thrown during output, then ios​::​badbit is turned on in
*this's error state. If (exceptions()&badbit) != 0 then the exception is
rethrown. Whether or not an exception is thrown, the sentry object is
destroyed before leaving the formatted output function. If no exception
is thrown, the result of the formatted output function is *this."

Huh!

Nowhere does this say anything about badbit (except as a result of
exceptions). Doesn't seem to happen in your case.

But, anyway, the libary code does one thing for string output (after
creating the sentry object):

     if (!_Ok) {
         _State |= _Ostr_t::badbit;
     } else { // state okay, insert characters

     }

and another thing for all other types

     if (_Ok) { // state okay, insert

     }


So, why do they do that? Historical reasons? I don't know.

My guess is that this is not what the standard intended, but perhaps
something MS has done "always". Or that writing to a closed file with
eof-status isn't on the top list of use cases tested.


     Bo Persson

Received on 2019-11-07 06:06:42