私はこのstd::ofstream::write
メソッドのめちゃくちゃ奇妙な振る舞いを目撃しました。私は、ビットマップをファイルに保存することを含む、WindowsのBMPファイル形式の独自の処理を書いています-これは紹介です。std::ofstream
これは、オブジェクトへの参照を指定して、ビットマップファイルのヘッダーを書き込むためのサブルーチンです。
void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
word w;
dword dw;
char const* cw = reinterpret_cast<char*>(w );
char const* cdw = reinterpret_cast<char*>(dw);
uint const sw = sizeof(w );
uint const sdw = sizeof(dw);
fout.write(&sig1, sizeof(sig1));
fout.write(&sig2, sizeof(sig2));
dw = toLittleEndian(size); fout.write(cdw, sdw);
w = toLittleEndian(reserved1); fout.write(cw , sw );
w = toLittleEndian(reserved2); fout.write(cw , sw );
dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
}
ここでマークする唯一のことは、sig1
とsig2
が両方ともタイプchar
、sizeof(word) = 2
およびであるということsizeof(dword) = 4
です。このコードにより、ファイルに1バイトが2回書き込まれ、次に4バイトのチャンク、2つの2バイトのチャンク、最後に4バイトのチャンクが書き込まれます。
結果の16進ダンプを見てください(以下にもいくつかありますが、無視してください)。
00000000 42 4d 42 4d 00 00 00 05 00 05 42 4d 00 00 28 00 |BMBM......BM..(.|
sig1
とsig2
は2回出力され、適切な値は実際にはとB
でM
、最初と何らかの奇妙な理由で11バイト目と12バイト目にも出力されます。この行の中で他の値を認識していません。しかし、すべての間にデバッグバイトを追加するとどうなるか見てくださいwrite
:
void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
word w;
dword dw;
char const* cw = reinterpret_cast<char*>(w );
char const* cdw = reinterpret_cast<char*>(dw);
uint const sw = sizeof(w );
uint const sdw = sizeof(dw);
char nil = '*';
fout.write(&sig1, sizeof(sig1));
fout.write(&nil, sizeof(nil));
fout.write(&sig2, sizeof(sig2));
fout.write(&nil, sizeof(nil));
dw = toLittleEndian(size); fout.write(cdw, sdw);
fout.write(&nil, sizeof(nil));
w = toLittleEndian(reserved1); fout.write(cw , sw );
fout.write(&nil, sizeof(nil));
w = toLittleEndian(reserved2); fout.write(cw , sw );
fout.write(&nil, sizeof(nil));
dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
fout.write(&nil, sizeof(nil));
}
16進ダンプは
00000000 42 2a 4d 2a 6c 3b 78 a0 2a 00 05 2a 00 05 2a 6c |B*M*l;x?*..*..*l|
00000010 3b 78 a0 2a 28 00 00 00 28 00 00 00 28 00 00 00 |;x?*(...(...(...|
それは完全に大丈夫のようです。重複はなく、文字列をバイト*
のシーケンスに分割します。1-1-4-2-2-4
誰かが私がこれの理由を見つけるのを手伝ってもらえますか?コンパイル時のバグですか?Mac OS X Leopardで-O2を使用gcc version 4.0.1 (Apple Inc. build 5490)
していますが、他のレベルでは何も変更されていません。