C2x, 7.21.9.2 La función fseek:
Sinopsis
#include <stdio.h> int fseek(FILE *stream, long int offset, int whence);
¿Por qué fseek tiene long int offset en lugar de long long int offset ?
Parece que en sistemas operativos con modelo de datos LLP64 o ILP32 (ej. Microsoft Windows) el 2147483647 (2 GB) puede resultar insuficiente.
Nota: lseek de POSIX tiene off_t offset , donde off_t " no está muy rigurosamente definido ".
El estándar C se formalizó en 1990 cuando la mayoría de los discos duros tenían menos de 2 GB. El prototipo de fseek() ya estaba en uso generalizado con un desplazamiento de tipo long y 32 bits parecían lo suficientemente grandes para todos los propósitos, especialmente porque la llamada al sistema correspondiente ya usaba la misma API. fgetpos() y fsetpos() para sistemas de archivos exóticos donde un desplazamiento largo simple no contenía toda la información necesaria para la búsqueda, pero mantuvo el tipo fpos_t opaco.
Después de algunos años, cuando se hicieron necesarias las compensaciones de 64 bits, muchos sistemas operativos agregaron versiones de 64 bits de las llamadas al sistema y POSIX introdujo fseeko() y ftello() para proporcionar una interfaz de alto nivel para compensaciones más grandes. Estas extensiones ya no son necesarias para las versiones de 64 bits de los sistemas operativos comunes (Linux, OS/X), pero Microsoft decidió mantener su tipo long , o más precisamente LONG , en 32 bits, solidificando este problema y otros también, como size_t es más grande que unsigned long . Esta desafortunada decisión afecta a los desarrolladores de C en plataformas Win64 desde entonces y los obliga a usar API no portátiles para archivos de gran tamaño.
Cambiar los prototipos de fseek y ftell crearía más problemas con el software existente, ya que rompería la compatibilidad, por lo que no sucederá.
Algunas otras deficiencias históricas son aún más sorprendentes, como el prototipo de fgets :
char *fgets(char * restrict s, int n, FILE * restrict stream); Por qué usaron int en lugar de size_t es un misterio: en 1990, int y size_t tenían el mismo tamaño en la mayoría de las plataformas y no tenía sentido pasar un valor negativo de todos modos. Nuevamente, esta API inconsistente llegó para quedarse.