写入默认构造的fstream:未定义的行为?

时间:2009-09-01 19:47:30

标签: c++ file-io fstream

请考虑以下事项:

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

使用VC 8.0构建时没有任何抱怨,但在使用VC 10.0 beta构建时会崩溃。

我有一些遗留代码实际上依赖于VC 8行为,我们从basic_fstream继承以添加功能:

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

在某些情况下,检查附加状态而不会产生磁盘I / O(例如测试写入)是有益的。

我假设这是未定义的行为,我很幸运它在VC 8中没有崩溃。那就是说,我已经有足够的问题来评估VS 2010 beta了,我想确定一下。谁能在那里明确地说出来?

编辑: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

在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

此外,在Ubuntu上使用gcc-4.3.3编译并运行时没有错误。

***编辑:

经过多次挖掘,看来这实际上是Visual Studio 2010 Beta 1中的一个错误。

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

根据这份报告,它已在官方发布中修复。

感谢您的所有投入。

1 个答案:

答案 0 :(得分:2)

您是否检查过流状态设置为失败或错误时是否启用了抛出异常?因为C ++标准说下面的'写'方法: -

  

27.6.2.7。未格式化的输出函数

     

点:-5

     

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

     

效果:表现为未格式化   输出功能(如   27.6.2.7,第1段)。构造一个岗哨对象后,获得   从连续插入的字符   第一个数组的位置   元素由s指定。   插入字符直到   发生以下情况:

  • 插入n个字符;
  • 在输出序列中插入失败(在这种情况下函数调用setstate badbit),这可能会抛出ios_base :: failure(27.4.4.3))。

这意味着最多testfile.fail()返回true。它理想情况下不应该崩溃。 我怀疑是一个例外被抛出而没有被抓住(但也许我完全错了)。