C ++ використовує streamoff
тип для відображення зміщення в потоці (файл) і визначається наступним чином у [stream.types]:
using streamoff = implementation-defined ;
Тип streamoff є синонімом одного з підписаних основних інтегральних типів достатнього розміру, щоб представити максимально можливий розмір файлу для операційної системи. 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
(як це пропонує стандарт), це може призвести до переходу вниз long
при виклику fseek(file, width * off, whence)
(що призводить до потенційно важкої діагностики помилок). Це ставить під сумнів ціле обгрунтування впровадження streamoff
типу.
Це навмисне чи дефект стандарту?
seekoff
обов'язково використовується fseek
під кришкою. Швидше, поведінка (імовірно знайома?) fseek
Використовується для пояснення того, що seekoff
робиться.
fseek
, поки вона робить щось з тим же ефектом. Але fseek
зі зміщенням менше LONG_MIN
або більше, ніж LONG_MAX
це не має ефекту, тому пояснення в кращому випадку є неповним, принаймні для реалізацій, де streamoff
ширше, ніж long
.