在编写涉及文件的C代码时,我应该定义_FILE_OFFSET_BITS = 64吗?

时间:2018-01-06 12:59:06

标签: c libc large-file-support

我注意到一些C项目正在编译使用_FILE_OFFSET_BITS=64访问文件的代码。现在,在我的系统(64位)上,添加或删除它似乎没有多大作用 - 但也许在其他系统上它可以做到。

我应该何时使用_FILE_OFFSET_BITS=64(或任何其他值)?或者,或者,我需要检查什么以确保我实际上不需要它?

2 个答案:

答案 0 :(得分:2)

是的,请定义它。

在64位平台上使用<?xml version="1.0" encoding="UTF-8"?> <Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:28.3036616Z" version="12.0"> <uR requestID="AM02050384" requestSource="AM02" updateOrigin="CIS"> <TS rid="201801037171519" ssd="2018-01-03" uid="G71519"> <ns3:Location tpl="GLYNDE" wtp="01:25:08"> <ns3:pass at="01:31" src="TD" /> <ns3:plat conf="true" platsrc="A" platsup="true">2</ns3:plat> <ns3:length>8</ns3:length> </ns3:Location> </TS> </uR> </Pport> <?xml version="1.0" encoding="UTF-8"?> <Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:29.1772672Z" version="12.0"> <uR requestID="0000000000046386" requestSource="at21" updateOrigin="CIS"> <TS rid="201801038706030" ssd="2018-01-03" uid="W06030"> <ns3:Location pta="01:25" ptd="01:26" tpl="DARTFD" wta="01:25" wtd="01:26"> <ns3:arr at="01:31" src="TD" /> <ns3:dep et="01:32" etmin="01:27" src="Darwin" /> <ns3:plat conf="true" platsrc="A">4</ns3:plat> </ns3:Location> </TS> </uR> </Pport> <?xml version="1.0" encoding="UTF-8"?> <Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:30.1912737Z" version="12.0"> <uR updateOrigin="TD"> <TS rid="201801027160109" ssd="2018-01-02" uid="G60109"> <ns3:Location tpl="BRINKLW" wtp="01:34:30"> <ns3:pass at="01:31" src="TD" /></ns3:Location> </TS> </uR> </Pport> <?xml version="1.0" encoding="UTF-8"?> <Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:31.2052802Z" version="12.0"> <uR updateOrigin="TD"> <TS rid="201801036763188" ssd="2018-01-03" uid="C63188"> <ns3:Location tpl="AMBERGJ" wtp="02:04:30"> <ns3:pass et="01:38" src="TD" /></ns3:Location> </TS> </uR> </Pport> 没有任何缺点。在32位平台上如果你正在做一些可能需要寻找/告知偏移量超过2³¹的文件的东西,你需要这个或准备使用单独< / em> 64位函数。

行为不是默认行为的原因是C标准和POSIX指定-D_FILE_OFFSET_BITS=64用于各种功能 - 在32位Unixen上,long int通常可以保持值仅限2³¹。现在,long int的使用将保证使用-D_FILE_OFFSET_BITS=64lseek等的代码将继续在32位系统中工作,就像在64位系统中一样。

引用GLibc功能测试宏:

  

宏:ftello

     

此宏确定应使用哪个文件系统接口,一个替换另一个。鉴于 _FILE_OFFSET_BITS 使64位接口可用作附加接口, _LARGEFILE64_SOURCE 允许64位接口替换旧接口。

     

[...]

     

如果将宏定义为值64,则大文件接口将替换旧接口。即,函数不能以不同的名称提供(与_FILE_OFFSET_BITS一样)。相反,旧的函数名称现在引用了新函数,例如,对fseeko的调用现在确实调用了fseeko64。

     

只有在系统提供处理大文件的机制时才应选择此宏。在64位系统上,由于_LARGEFILE64_SOURCE函数与普通函数相同,因此该宏无效。

fseeko(3)手册页:

  

在某些体系结构上,*64off_t都是32位类型,但定义long且值为64(包含任何头文件之前)将转为_FILE_OFFSET_BITS进入64位类型。

答案 1 :(得分:0)

Autoconf为此提供了一个宏:AC_SYS_LARGEFILE。它通过在配置时检测默认情况下off_t是否已经是64位类型来添加所需选项,如果不是,则将_FILE_OFFSET_BITS设置为64是否将其转换为64位类型。它还以相同的方式检测另一个预处理器宏_LARGE_FILES,用于某些非GNU系统(根据注释的“AIX风格主机”)。

如果您使用的是autoconf,则可以直接使用此宏。如果你没有使用它,你可以重新实现同样的逻辑。

这些宏位于保留名称空间中供实现使用,因此最好不要将它们设置在不使用GNU的方式的系统上。它们可能会对其他系统产生意外影响。虽然我怀疑在定义这些宏时没有故意破坏的恶意实现,但是某些实现(可能是未来的实现)可以合理地使用具有这些相同名称的宏,巧合的是,出于微妙的不同目的。