我注意到一些C项目编译使用_FILE_OFFSET_BITS=64
访问文件的代码。现在,在我的系统(64 位)上,添加或删除它似乎没有多大作用 - 但也许在其他系统上它确实如此。
何时应使用_FILE_OFFSET_BITS=64
(或任何其他值)?或者,或者,我需要检查什么以确保我实际上不需要它?
是的,请定义它。
在 64 位平台上使用-D_FILE_OFFSET_BITS=64
没有任何缺点。在 32 位平台上,如果您正在执行可能需要在偏移量超过 2³¹ 的文件上查找/告知任何内容的操作,则需要此函数或准备使用单独的64 位函数。
该行为不是默认行为的原因是 C 标准和 POSIX 指定long int
用于各种功能 - 在 32 位 Unixen 上,long int
通常只能保存最多 2³¹ 的值。现在,使用-D_FILE_OFFSET_BITS=64
将保证使用lseek
、ftello
等的代码将继续在 32 位系统中工作,就像在 64 位系统中一样。
引用 GLibc 功能测试宏:
宏:
_FILE_OFFSET_BITS
此宏确定应使用哪个文件系统接口,一个替换另一个。
_LARGEFILE64_SOURCE
使 64 位接口可用作附加接口,而_FILE_OFFSET_BITS
允许 64 位接口替换旧接口。[...]
如果宏定义为值 64,则大文件接口将替换旧接口。 即,函数不以不同的名称提供(就像它们一样
_LARGEFILE64_SOURCE
)。相反,旧的函数名称现在引用了新函数,例如,对fseeko的调用现在确实调用了fseeko64。仅当系统提供处理大文件的机制时,才应选择此宏。在 64 位系统上,此宏不起作用,因为
*64
函数与普通函数相同。
fseeko(3)
手册页:
在某些体系结构上,
off_t
和long
都是 32 位类型,但使用值 64(在包含任何头文件之前)定义_FILE_OFFSET_BITS
会将off_t
转换为 64 位类型。
Autoconf 为此提供了一个宏:AC_SYS_LARGEFILE
.它通过在配置时检测off_t
是否默认已经是 64 位类型,如果不是,则_FILE_OFFSET_BITS
设置为64
是否将其转换为 64 位类型来添加所需的选项。它还检测另一个预处理器宏,_LARGE_FILES
,以相同的方式,在某些非GNU系统上使用(根据注释为"AIX风格的主机")。
如果您使用的是自动会议,则可以直接使用此宏。如果不使用它,可以重新实现相同的逻辑。
这些宏位于保留的名称空间中,供实现使用,因此最好不要将它们设置在不以 GNU 方式使用它们的系统上。它们可能会对其他系统产生意想不到的影响。虽然我怀疑在定义这些宏时没有恶意实现故意中断,但一些实现(可能是未来的实现)可能会合法地使用这些相同名称的宏,巧合的是,出于微妙不同的目的。