View Single Post
  #1 (permalink)  
Old 10-20-2005, 01:51 PM
bgneal@gmail.com
Guest
 
Posts: n/a
Default streambuf, badbit, and exceptions

I am trying to write a custom streambuf and figure all of this IOStream
stuff out. In my custom streambuf, the underlying transport that I am
encapsulating can fail on me. I would like to communicate this to the
user by having the badbit get set when this happens.

It is not entirely clear to me how a streambuf can cause the badbit to
get set in the "owner" stream. After doing some googling, it looks like
this can be achieved if the streambuf throws an exception from one of
its operations.

Is this correct?

I wrote a test program to see if this works:

#include <iostream>
#include <ostream>
#include <istream>
#include <stdexcept>

class DumbStreambuf : public std::streambuf
{
public:

protected:
virtual int underflow()
{
std::cout << "In underflow" << std::endl;
throw std::runtime_error("DumbStreambuf underflow");
}

virtual int overflow(int /*c*/)
{
std::cout << "In overflow" << std::endl;
throw std::runtime_error("DumbStreambuf overflow");
}
};

int main()
{
DumbStreambuf ds;
std::iostream ios(&ds);

unsigned long bits = ios.exceptions();
std::cout << "bits = " << std::hex << bits << std::dec << std::endl;

try
{
int n;
ios >> n;
}
catch (const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}

std::cout << std::boolalpha <<
"good = " << ios.good() <<
" bad = " << ios.bad() <<
" eof = " << ios.eof() <<
" fail = " << ios.fail() << std::endl;

ios.clear();

try
{
int n = 0;
ios << n;
}
catch (const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}

std::cout << std::boolalpha <<
"good = " << ios.good() <<
" bad = " << ios.bad() <<
" eof = " << ios.eof() <<
" fail = " << ios.fail() << std::endl;

return 0;
}

Here is the output that I get when I build this with g++ 3.4.4 under
Cygwin.

$ ./test
bits = 0
In underflow
Exception: DumbStreambuf underflow
good = true bad = false eof = false fail = false
In overflow
good = false bad = true eof = false fail = true

It looks like that if my streambuf throws an exception during a write
operation (overflow), the exception is caught and the bad bit is set.

But during an input operation (underflow), the bad bit is not getting
set, and my exception is either escaping or getting caught and
re-thrown.

Is this behavior correct? If so, why the asymmetry?

I looked at the STL implementation, and I did see a try/catch block in
the operator>>(int&) function...I'm really confused...

Thanks,
BN


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote