According to C99, the prototype for ftell
is:
long int ftell(FILE *stream);
From what I undersood it should be the following instead:
fpos_t ftell(FILE *stream);
Why is that?
From §7.19.1-2
fpos_t
which is an object type other than an array type capable of recording all the information needed to specify uniquely every position within a file.
I understand that fpos_t
should be used to record a position within a file. So ftell
which returns a position within a file should be of that type. Instead it is:
signed
long
which can be too small or too big to access a file on certain architectures. The ftell() function obtains the current value of the file position indicator for the stream pointed to by stream. Behavior for binary streams: ANSI states that the ftell() function returns relative byte offsets from the beginning of the file for binary files.
Use ftell with fseek to return to file locations correctly. On error, ftell returns –1L.
fpos_t is a non-array complete object type, can be used to store (by fgetpos) and restore (by fsetpos) the position and multibyte parser state (if any) for a C stream.
Notice that fpos_t
is
[...] a complete object type other than an array type capable of recording all the information needed to specify uniquely every position within a file.
So it can can be even a structure, totally unusable for anything else besides calling fsetpos
!
On the other hand the return value of ftell
is a scalar which is guaranteed to be possible to use in telling the exact byte position in a binary file:
For a binary stream, the value is the number of characters from the beginning of the file.
Other than that, the reason is backwards-compatibility. ftell
debuted in C89, and perhaps then the expectation was that long
would scale fast enough to contain all file sizes, something that is not always true nowadays. Unfortunately it is not possible to change the type returned by ftell
but it is too late to change that now - even those platforms that support larger files now have functions with another name, such as ftello
.
the signedness is required because the function returns -1
on error.
From the manpage of fgetpos()/fsetpos()
:
On some non-UNIX systems, an fpos_t object may be a complex object and these routines may be the only way to portably reposition a text stream.
whereas ftell()
is required to return the offset of the file pointer in the file. These are completely different interfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With