C ++ menggunakan streamoff
tipe untuk mewakili offset dalam aliran (file) dan didefinisikan sebagai berikut di [stream.types]:
using streamoff = implementation-defined ;
Jenis aliran adalah sinonim untuk salah satu tipe integral dasar yang ditandatangani dari ukuran yang cukup untuk mewakili ukuran file maksimum yang mungkin untuk sistem operasi. 287)
287) Biasanya panjang.
Ini masuk akal karena memungkinkan untuk mencari di dalam file besar (tidak seperti menggunakan long
, yang mungkin hanya 32 bit lebar).
[filebuf.virtuals] mendefinisikan basic_filebuf
fungsi untuk mencari di dalam file sebagai berikut:
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
off_type
setara dengan streamoff
, lihat [iostreams.limits.pos]. Namun, standar kemudian menjelaskan efek fungsi. Saya kesal dengan kalimat terakhir, yang membutuhkan panggilan ke fseek
:
Efek : Biarkan
width
dilambangkana_codecvt.encoding()
. Jikais_open() == false
, atauoff != 0 && width <= 0
, maka operasi penentuan posisi gagal. Jika tidak, jikaway != basic_ios::cur
atauoff != 0
, dan jika operasi terakhir adalah output, maka perbarui urutan output dan tuliskan urutan unshift. Selanjutnya, cari ke posisi baru: jikawidth > 0
, panggilanfseek(file, width * off, whence)
, atau panggilanfseek(file, 0, whence)
.
fseek
menerima long
parameter. Jika off_type
dan streamoff
didefinisikan sebagai long long
(seperti yang disarankan oleh standar), ini dapat menyebabkan konversi turun ke long
saat menelepon fseek(file, width * off, whence)
(mengarah ke kemungkinan sulit mendiagnosis bug). Ini mempertanyakan seluruh alasan untuk memperkenalkan streamoff
jenis di tempat pertama.
Apakah ini disengaja atau cacat dalam standar?
seekoff
perlu digunakan difseek
bawah tenda. Sebaliknya, perilaku (mungkin akrab?)fseek
Digunakan untuk menjelaskan apa yangseekoff
sedang dilakukan.fseek
selama ia melakukan sesuatu dengan efek yang sama. Tetapifseek
dengan offset kurang dariLONG_MIN
atau lebih besar dariLONG_MAX
tidak memiliki efek, sehingga penjelasannya paling tidak lengkap, setidaknya untuk implementasi di manastreamoff
lebih luas darilong
.Jawaban:
Saya pikir kesimpulan bahwa Anda menggambar dari ini, bahwa ada ketidakcocokan antara aliran C ++ dan
fseek
yang akan menyebabkan bug runtime, tidak benar. Situasinya tampaknya:Pada sistem di mana
long
64 bit,streamoff
didefinisikan sebagailong
, danseekoff
fungsinya memanggilfseek
.Pada sistem di mana
long
32 bit tetapi OS mendukung offset file 64-bit,streamoff
didefinisikan sebagailong long
danseekoff
memanggil fungsi yang disebut salah satufseeko
ataufseeko64
yang menerima offset 64-bit.Berikut cuplikan dari definisi
seekoff
pada sistem Linux saya:LFS adalah singkatan Large File Support .
Kesimpulan: Sementara standar menunjukkan definisi untuk
streamoff
yang konflik seolah-olah dengan persyaratan bahwaseekoff
Invokefseek
, desainer perpustakaan memahami bahwa mereka harus memanggil varianfseek
yang menerima berbagai macam offset yang mendukung OS.sumber
The situation seems to be:
- Situasi adalah bahwa pelaksanaannya tidak diperbolehkan untuk tidak memanggilfseek
diseekoff
. Itu harus memanggilfseek
, tidak, standar mengatakan itu harus. Saya bisa berpendapat bahwa implementasi ini tidak valid. Saya percaya itu tidak menjawab pertanyaan. Och, ditemukan llvm , ia memanggilfseeko
._fseeki64
fungsi ini; yang juga tampaknya melanggar apa yang dikatakan standar.fseek
. Di tempat lain standar menggambarkan sesuatu sebagai "seolah-olah dengan meneleponfseek(...)
." Jika itu sangat peduli tentang panggilan secara harfiahfseek
, pernyataan itu akan berbeda. Serius, apa yang akan Anda lakukan, jika Anda menerapkan pustaka C ++? Apakah Anda bersikeras untuk memanggilfseek
dengan 32 bit yang lebih rendah dari offset file 64-bit, karena sebuah dokumen memberitahu Anda untuk melakukannya? Apakah pelanggan Anda akan berterima kasih untuk itu?