C++ uses the streamoff
type to represent an offset within a (file) stream and is defined as follows in [stream.types]:
using streamoff = implementation-defined ;
The type streamoff is a synonym for one of the signed basic integral types of sufficient size to represent the maximum possible file size for the operating system. 287)
287) Typically long long.
This makes sense because it allows for seeking within large files (as opposed to using long
, which may be only 32 bits wide).
[filebuf.virtuals] defines basic_filebuf
's function to seek within a file as follows:
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
off_type
is equivalent to streamoff
, see [iostreams.limits.pos]. However, the standard then goes on to explain the function's effects. I'm irritated by the very last sentence, which requires a call to fseek
:
Effects: Let
width
denotea_codecvt.encoding()
. Ifis_open() == false
, oroff != 0 && width <= 0
, then the positioning operation fails. Otherwise, ifway != basic_ios::cur
oroff != 0
, and if the last operation was output, then update the output sequence and write any unshift sequence. Next, seek to the new position: ifwidth > 0
, callfseek(file, width * off, whence)
, otherwise callfseek(file, 0, whence)
.
fseek
accepts a long
parameter. If off_type
and streamoff
are defined as long long
(as suggested by the standard), this could lead to a down conversion to long
when calling fseek(file, width * off, whence)
(leading to potentially hard to diagnose bugs). This calls into question the whole rationale for introducing the streamoff
type in the first place.
Is this intentional or a defect in the standard?