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_-

C++使用
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
    ,因为文档会告诉您这样做吗?您的客户会为此感谢您吗?