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
widthdenotea_codecvt.encoding(). Ifis_open() == false, oroff != 0 && width <= 0, then the positioning operation fails. Otherwise, ifway != basic_ios::curoroff != 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?