5

C2x, 7.21.9.2 fseek 函数:

概要

#include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);

为什么fseeklong int offset而不是long long int offset

似乎在具有LLP64 或 ILP32数据模型的操作系统(例如 Microsoft Windows)上,2147483647(2 GB)可能是不够的。

注意:POSIX 的lseekoff_t offset,其中off_t定义不是很严格”。

4

1 回答 1

3

C 标准于 1990 年正式制定,当时大多数硬盘驱动器都小于 2 GB。for 的原型fseek()已经被广泛使用,带有long类型偏移,32 位似乎足以满足所有目的,特别是因为相应的系统调用已经使用了相同的 API。他们确实为奇异的文件系统添加了fgetpos()fsetpos(),其中一个简单的长偏移量没有携带所有必要的信息来寻找,但保持fpos_t类型不透明。

几年后,当 64 位偏移量变得必要时,许多操作系统添加了 64 位版本的系统调用并引入了 POSIXfseeko()ftello()为更大的偏移量提供高级接口。这些扩展对于 64 位版本的通用操作系统(linux、OS/X)不再是必需的,但微软决定将其保留为 32 位long,或者更准确地说LONG,将其类型保留为 32 位,从而巩固了这个问题以及其他问题,例如size_t更大比unsigned long。从那时起,这个非常不幸的决定一直困扰着 Win64 平台上的 C 开发人员,并迫使他们对大文件使用不可移植的 API。

更改fseekftell原型会为现有软件带来更多问题,因为它会破坏兼容性,因此不会发生。

其他一些历史缺陷更令人惊讶,例如 的原型fgets

char *fgets(char * restrict s, int n, FILE * restrict stream);

他们为什么使用int而不是size_t是一个谜:早在 1990 年,intsize_t大多数平台上都有相同的大小,无论如何传递负值是没有意义的。同样,这种不一致的 API 将继续存在。

于 2022-02-07T17:00:01.417 回答