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.