views:

422

answers:

1

Consider the following:

std::basic_fstream<char> testfile;
testfile.write(reinterpret_cast<const char*>(&someInt), sizeof(int));
testfile.close();

This runs with no complaint when built with VC 8.0, but crashes when built with VC 10.0 beta.

I have some legacy code that actually relies on the VC 8 behavior, where we inherit from basic_fstream to add functionality:

class myFile : public basic_fstream<char> {
    public:
    void myWrite(const char* data, std::streamsize len) {
       write(data, len);
       // update some state variables (checksum, etc)
    }
};

There are cases where it is beneficial to inspect the additional state without incurring the disk I/O (e.g. test writes).

I'm assuming this is undefined behavior, and I'm lucky it doesn't crash in VC 8. That said, I've had enough issues evaluating VS 2010 beta that I'd like to be sure. Can anyone out there say definitively?

EDIT: Call stack in VS 2010:

ostream::write
ostream::sentry ctor
istream::_Sentry_base ctor
fstream::_Lock
_file.c::_lock_file
crashes on EnterCriticalSection( &(((_FILEX *)pf)->lock) ), pf is null

Call stack on VS 2005:

ostream::write
ostream::sentry ctor
ostream::_Sentry_base ctor // different
streambuf::_Lock
_Mutex::_Lock()
_Mtxlock in xmtx.c
EnterCriticalSection(_Mtx), where _Mtx is valid

Also, compiles and runs with no errors with gcc-4.3.3 on Ubuntu.

*** EDIT:

After more digging, it appears that this in fact is a bug in Visual Studio 2010 Beta 1.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=456890

According to this report, it has been fixed for the official release.

Thanks for all of your input.

+2  A: 

Have you checked whether throwing exceptions are enabled when the stream state is set to fail or bad? Because the C++ Standard says the following abt 'write' methdod :-

27.6.2.7. Unformatted output functions

Point:-5

basic_ostream& write(const char_type* s, streamsize n);

Effects: Behaves as an unformatted output function (as described in 27.6.2.7, paragraph 1). After constructing a sentry object, obtains characters to insert from successive locations of an array whose first element is designated by s. Characters are inserted until either of the following occurs:

  • n characters are inserted;
  • inserting in the output sequence fails (in which case the function calls setstate badbit), which may throw ios_base::failure (27.4.4.3)).

This means that at most testfile.fail() returns true. It should ideally not crash. I suspect an exception is being thrown and not caught (But maybe i am totally wrong).

Abhay
Ryan
Wow, don't know what happened to my formatting there, edited the post instead.
Ryan
@Ryan: It semms a little strange to me. Why is the runtime trying to lock istream when it should be locking ostream. May be you can try `std::basic_ofstream<char>` instead of `std::basic_fstream<char>`.
Abhay
@Abnay: See my answer below, as you suspect it is a bug in VS's implementation. Thanks for your help.
Ryan