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
.