Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the return type for ftell not fpos_t?

Tags:

c

c99

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
  • of type long which can be too small or too big to access a file on certain architectures.
like image 848
nowox Avatar asked Jul 25 '19 11:07

nowox


People also ask

What is the return type of Ftell function?

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.

What does Ftell return on error?

Use ftell with fseek to return to file locations correctly. On error, ftell returns –1L.

What is fpos_ t in C?

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.


2 Answers

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.

like image 147

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.

like image 40
Ctx Avatar answered Nov 02 '22 06:11

Ctx