Thursday, November 1, 2012

Is it necessary to manually close ifstream/ofstream/fstream

The short answer is NO.

By looking into the GCC implementation of fstream, we can see that the destructor of the class does nothing.

  typedef basic_fstream<char>       fstream;    ///< @isiosfwd



       *  @brief  The destructor does nothing.
       *  The file is closed by the filebuf object, not the formatting
       *  stream.
      { }

The comments of the destructor give you a hint that the file will be closed. Let us look at the filebuf object it mentions. It is a private member of the basic_fstream class. Its destructor will be called when it is out of scope, i.e. when the fstream object is destroyed.

      typedef basic_filebuf<char_type, traits_type>     __filebuf_type;


      __filebuf_type    _M_filebuf;

The destructor of basic_filebuf does call the close() function to close the associated file.

       *  @brief  The destructor closes the file first.
      { this->close(); }

So no, we do not need to explicitly call fstream::close() to close the file. After open a file with fstream/ifstream/ofstream, it is safe to throw an exception without manually close the file first. When the fstream/ifstream/ofstream object is out of scope, the file will be closed automatically.

However, you can explicitly call the close() function to close it and release the resource if the fstream object will not be out of scope for a while.


Anonymous said...

GCC will most likely inline the empty destructor call. If it doesn't, then increase the -O, or most likely it's something you should not bother with.

Do not optimize early. Never rely on implementation details (what about a different version of GCC?). Do not give optimization advice until you've measured the gain (how many files is the average program going to close in its life, and how many millisecs do you have measured to have saved?). Never believe you're smarter than the STL. NEVER.

Anonymous said...

Sorry, I meant: GCC will optimize away the additional close() call.

Get This <