C++ 为什么C++;标准句柄文件的查找方式?
C++使用C++ 为什么C++;标准句柄文件的查找方式?,c++,file,language-lawyer,seek,c++20,C++,File,Language Lawyer,Seek,C++20,C++使用streamoff类型表示(文件)流中的偏移量,在[stream.types]中定义如下: 使用streamoff=定义的实现 streamoff类型是一种有符号基本整数类型的同义词,其大小足以表示操作系统可能的最大文件大小。(287) 287)通常很长 这是有意义的,因为它允许在大文件中查找(而不是使用long,后者可能只有32位宽) [filebuf.virtuals]定义了basic\u filebuf在文件中查找的函数,如下所示: pos_-type seekoff(off_-
streamoff
类型表示(文件)流中的偏移量,在[stream.types]中定义如下:
使用streamoff=定义的实现代码>
streamoff类型是一种有符号基本整数类型的同义词,其大小足以表示操作系统可能的最大文件大小。(287)
287)通常很长
这是有意义的,因为它允许在大文件中查找(而不是使用long
,后者可能只有32位宽)
[filebuf.virtuals]定义了basic\u filebuf
在文件中查找的函数,如下所示:
pos_-type seekoff(off_-type off,ios_-base::seekdir-way,ios_-base::openmode-which=ios_-base::in | ios_-base::out)覆盖代码>
off\u type
相当于streamoff
,请参见[iostreams.limits.pos]。然而,标准接着解释了功能的影响。最后一句话让我很恼火,它需要调用fseek
:
效果:让width
表示a_codevt.encoding()
。如果打开()==false
,或关闭!=0和宽度(&W)
0
,调用fseek(文件,宽度*关闭,从何处开始)
,否则
调用fseek(文件,0,何处)
fseek
接受long
参数。如果off\u type
和streamoff
被定义为long
(根据标准建议),这可能会导致调用fseek(文件,宽度*off,从何处)
(导致潜在的难以诊断的错误)时向下转换为long
。这就对首先引入streamoff
类型的整个原理提出了质疑
这是故意还是缺陷?
< P>我认为,你从中得出的结论是,C++流和<代码> fScript < /C> >之间的不匹配会导致运行时错误,这是不正确的。情况似乎是:
在long
为64位的系统上,streamoff
被定义为long
,并且seekoff
函数调用fseek
在long
为32位但操作系统支持64位文件偏移量的系统上,streamoff
被定义为long
,并且seekoff
调用一个名为fseeko
或fseeko64
的函数,该函数接受64位偏移量
下面是我的Linux系统上的seekoff
定义的片段:
#ifdef _GLIBCXX_USE_LFS
if (!fseeko64(_M_file, __off, __whence))
__ret = std::streampos(ftello64(_M_file));
#else
if (!fseek(_M_file, __off, __whence))
__ret = std::streampos(std::ftell(_M_file));
#endif
LFS代表
结论:虽然标准建议对streamoff
进行定义,但表面上与seekoff
调用fseek
的要求相冲突,库设计人员知道,他们必须调用fseek
的变体,该变体接受操作系统支持的全部偏移量。缺陷看起来像。我想我看到了gcc libstdc++使用的。一方面,它看起来不像seekoff
在引擎盖下必然使用fseek
。相反,fseek
的行为(可能很熟悉?)被用来解释seekoff
在做什么。@jramsey这也是我的印象。然而,它的措辞似乎暗示了一个要求,而不是一个解释。@jramsey我同意“效果”部分可以合理地解释为,它实际上不必调用fseek
,只要它做的事情具有相同的效果。但偏移量小于LONG\u MIN
或大于LONG\u MAX
的fseek
没有效果,因此解释充其量是不完整的,至少对于streamoff
大于LONG
@ypnos的实现,我没有投反对票,我发现这个答案很有用。我猜有人投了反对票,因为它没有抓住要点。问题不在于有健全的实现在这方面忽略了标准,问题在于需要忽略标准才能使实现健全。情况似乎是:
-情况是不允许实现在seekoff
中调用fseek
。它必须调用fseek
,它没有,说它必须。我可以说这个实现是无效的。我相信它没有回答这个问题。Och发现,它调用fseeko
。仅供参考,VC++为该函数调用\u fseeki64
;这似乎也违反了标准的规定。这是一个实施者意识到问题而忽视标准的案例。我很高兴他们这么做了,但标准确实需要确定。有些人把标准看得太字面了。它并不要求实现真正调用名为fseek
的函数。在其他地方,该标准将某些内容描述为“仿佛通过调用fseek(…)
”。如果该标准如此在意从字面上调用fseek
,则该声明将有所不同。说真的,如果你正在执行C++库,你会怎么做?您会坚持使用64位文件偏移量的较低32位调用fseek
,因为文档会告诉您这样做吗?您的客户会为此感谢您吗?