{C++ etc.}

Latest Posts
Home | C++ Posts | Linux Posts | Programming Posts | Issue Tracking Posts

Saturday, March 20, 2010

fstream.clear()... How MS takes a working model and breaks it.

I've used fstreams in Linux/Solaris a lot of times and it's always been the same simple model.
  • Open
  • Process
  • Close

Recently, I was working on porting some Linux code to Windows and a strange thing happened (well a lot of strange things happened but this really had me dumbfounded :-|). I found that once an fstream is used to open a file, I can't re-use it even after calling close(). If I created a new fstream instance for each file, everything worked fine.
I found the solution here.
It reads:
It might be surprising to learn that this is in fact by design. The C++ Standard specifies that neither open or close clears the status flags of a stream. As such, the behavior you are seeing is in fact exactly what should happen.

The good news is that this is easy to work around, just add a call to the clear() method of the stream prior to opening it like so:
void open(const char* sFilename) {
m_stream.clear();//clear status of stream, as we're about to reuse it on a fresh file.
int nMode = std::ios::in | std::ios::_Nocreate;
m_stream.open(sFilename, nMode);
if (!m_stream) {
throw "Cannot open file";
m_isOpen = true;

What's bizarre about this is that you should not have to call clear(). "clear()" is a method specified in ios to be used to clear error flags. It's relevance for normal file handling operations is just beyond me.
This is another instance where MS has taken a working system and added unnecessary and irrelevant complexity in to it.

1 comment:

Daz said...

They break lots of different things, I'm working on an app which has to be compiled with the MSVC compiler and GCC and ran into a whole load of problems when specifying floating point formatting for iostreams and small degrees of precision!