【发布时间】:2020-04-07 06:45:15
【问题描述】:
C++ 使用streamoff 类型来表示(文件)流中的偏移量,并在 [stream.types] 中定义如下:
using streamoff = implementation-defined ;streamoff 类型是有符号基本整数类型之一的同义词,其大小足以表示操作系统的最大可能文件大小。第287章)
287) 通常很长很长。
这是有道理的,因为它允许在大文件中进行查找(而不是使用可能只有 32 位宽的 long)。
[filebuf.virtuals] 定义basic_filebuf 在文件中查找的函数如下:
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
off_type 等价于streamoff,参见 [iostreams.limits.pos]。但是,该标准随后继续解释该功能的效果。我被最后一句话激怒了,这需要致电fseek:
效果:让
width表示a_codecvt.encoding()。如果is_open() == false,或off != 0 && width <= 0,则定位操作失败。否则,如果way != basic_ios::cur或off != 0,并且 如果输出了最后一个操作,则更新输出序列并写入任何 unshift 序列。 接下来,寻找新的位置:如果width > 0,调用fseek(file, width * off, whence),否则 拨打fseek(file, 0, whence)。
fseek 接受 long 参数。如果off_type 和streamoff 被定义为long long(按照标准的建议),这可能会导致在调用fseek(file, width * off, whence) 时向下转换为long(导致潜在的难以诊断的错误)。这对首先引入 streamoff 类型的整个理由提出了质疑。
这是故意的还是标准中的缺陷?
【问题讨论】:
-
缺陷看起来像。
-
我想我看到 gcc libstdc++ 使用了fseeko64。
-
副手,它看起来不像
seekoff一定使用fseek在引擎盖下。相反,fseek的(可能是熟悉的?)行为用于解释seekoff正在做什么。 -
@jjramsey 这也是我的印象。但是,它的措辞方式似乎暗示了一种要求而不是一种解释。
-
@jjramsey 我同意“效果”部分可以合理地解释为它实际上不必调用
fseek,只要它具有相同的效果。但是偏移量小于LONG_MIN或大于LONG_MAX的fseek没有效果,因此解释充其量是不完整的,至少对于streamoff比long更宽的实现而言。
标签: c++ file language-lawyer seek c++20