2009-09-01 6 views
2

次の点を考慮してくださいデフォルトで構築されたfstreamへの書き込み:未定義の動作?

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

これは、VC 8.0で構築されたときに無苦情を実行しますが、VC 10.0ベータ版で構築されたときにクラッシュします。

私は実際に私たちは機能を追加するためにbasic_fstreamから継承VC 8の動作に依存しているいくつかのレガシーコードを持っている:

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ベータ版を評価していることが分かりました。そこにいる人は確実に言うことができますか?

EDIT:VS 2010でスタックを呼び出します:VS 2005

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

コールスタック:

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でエラーなしで実行されます。

*** EDIT:

より掘削した後、これが実際には、この報告書によると、Visual Studioで2010ベータ1

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

バグです、それがされていることが表示されます正式リリースのために修正されました。

入力いただきありがとうございます。

+3

私は、rdbufとしてヌルポインタを与えられたostreamに書き込むのはUBではないことが分かります。ostream os(0); os << "hello";すべての出力操作がbadbitを最初にチェックし、その場合は何もしないため、有効です。ストリームがヌルポインタによってバッファとして初期化されている場合、Badbitを設定します。 (一部の機能はまた、明示的に)(RDBUFの値をテストします。私は、これは当時ストリームが、私はIIRC結論に達していなかったファイルに対してどのように動作するかをルックアップしてみました。出力シーケンスがある場合にかかわらず、多くの機能は、」言います...」ファイルストリームが開いていない持つことができているようだ。 –

+0

? – xtofl

+0

ああ....未定義の動作のための 『UB』スタンドを何! – xtofl

答えて

2

ストリーム状態が失敗または不良に設定されているときにスロー例外が有効になっているかどうかを確認しましたか? C++標準は以下のabt 'write' methodを述べているので、 -

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を返すことを意味します。理想的にはクラッシュしないはずです。 私は例外が投げられていると思われ、捕まえられませんでした(しかし多分私は間違っています)。

+0

ios_base :: failureはスローされていません。興味深いことに、VS 2010のコールスタックは次のようになります。 ostream :: write ostream :: sそれはEnterCriticalSection(&(((_ FILEX *)PF)への呼び出しでクラッシュし、ここでエントリーコンストラクタ はistream :: _ Sentry_baseコンストラクタ のfstream _file.c で:: _ロック _lock_file - >ロック() PFがで nullですVS 2005、しかし、コールスタックは、次のようになります。 のostream :: のostreamを書く::歩哨CTOR のostream :: _ Sentry_base CTOR たstreambuf :: _ロック() _Mutex :: _ロック()xmtx.c EnterCriticalSectionで _Mtxlock (_Mtx)、_Mtxは有効です – Ryan

+0

うわー、私の書式に何が起こったのか分からず、代わりに投稿を編集しました。 – Ryan

+2

@ライアン:それは私にちょっと奇妙なものです。 ostreamをロックする必要があるときにランタイムがistreamをロックしようとするのはなぜですか? 'std :: basic_fstream 'の代わりに 'std :: basic_ofstream 'を試してみてください。 – Abhay

関連する問題