C++はstreamoff
タイプを使用して(ファイル)ストリーム内のオフセットを表し、[stream.types]で次のように定義されます。
_
using streamoff = implementation-defined ;
_タイプstreamoffは、オペレーティングシステムの最大可能ファイルサイズを表すのに十分なサイズの、署名された基本的な整数型の1つの同義語です。 287)
287)通常は長いです。
(long
を使用するのとは対照的に、32ビット幅しかない可能性があります)大きなファイル内でシークできるため、これは理にかなっています。
[filebuf.virtuals]は、ファイル内をシークする_basic_filebuf
_関数を次のように定義します。
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
_off_type
_はstreamoff
と同等です。[iostreams.limits.pos]を参照してください。ただし、標準は関数の影響を説明します。 fseek
の呼び出しを必要とする最後の文にイライラします。
効果:
width
にa_codecvt.encoding()
を示します。is_open() == false
、または_off != 0 && width <= 0
_の場合、位置決め操作は失敗します。それ以外の場合、_way != basic_ios::cur
_または_off != 0
_の場合、および最後の操作が出力された場合は、出力シーケンスを更新して、シフトなしのシーケンスを書き込みます。次に、新しい位置を探します。_width > 0
_の場合はfseek(file, width * off, whence)
を呼び出し、それ以外の場合はfseek(file, 0, whence)
を呼び出します。
fseek
はlong
パラメータを受け入れます。 _off_type
_およびstreamoff
が_long long
_として定義されている場合(標準で推奨)、これによりfseek(file, width * off, whence)
を呼び出すときにlong
へのダウンコンバージョンが発生する可能性があります(バグを診断するのは難しい)。これは、最初にstreamoff
型を導入する根拠全体に疑問を投げかけます。
これは意図的なものですか、それとも規格の欠陥ですか?
あなたがこれから引き出されている、C++ストリームとfseek
の間にランタイムバグにつながる不一致があるという結論は正しくないと思います。状況は次のようです:
long
が64ビットのシステムでは、streamoff
はlong
として定義され、seekoff
関数はfseek
を呼び出します。
long
が32ビットであるがOSが64ビットのファイルオフセットをサポートするシステムでは、streamoff
はlong long
として定義され、seekoff
はfseeko
またはfseeko64
は64ビットのオフセットを受け入れます。
Linuxシステムでのseekoff
の定義からのスニペットは次のとおりです。
#ifdef _GLIBCXX_USE_LFS
if (!fseeko64(_M_file, __off, __whence))
__ret = std::streampos(ftello64(_M_file));
#else
if (!fseek(_M_file, __off, __whence))
__ret = std::streampos(std::ftell(_M_file));
#endif
LFSは Large File Support の略です。
結論:標準はstreamoff
の定義がseekoff
がfseek
を呼び出す要件と表面的に矛盾することを提案している一方で、ライブラリ設計者はfseek
これは、OSがサポートするオフセットの全範囲を受け入れます。