【发布时间】:2018-07-22 20:43:33
【问题描述】:
在 fopen 的 C 标准中,关于以更新模式打开的文件 (C11 7.21.5.3/7),输出后跟输入需要对 fflush 或文件定位函数(fseek、fsetpos 或 rewind)的干预调用。但是,不需要任何文件定位函数来对输出缓冲区执行任何操作。
POSIX 标准对fopen 和更新模式保持相同的要求。与 C 标准一样,fsetpos 不需要对输出缓冲区进行任何操作。但是,将缓冲区写入文件需要fseek。
在 C 和 POSIX 的情况下,当 fsetpos 被调用时,符合标准的实现似乎可以随意丢弃写缓冲区,而 C 似乎允许 fseek 做同样的事情。我的第一个问题是我是否遗漏了标准中的相关内容。这意味着可移植应用程序必须调用 fflush(或在 POSIX 的情况下为 fseek/rewind)以确保在从输出切换到输入之前实际写入缓冲输出。
显然,丢弃写缓冲区违背了所有写函数的意图,我不知道有任何实现这样做或任何类似违反直觉的事情。我也知道我的意识有限,所以我的第二个问题是是否有任何符合要求的实现不能确保缓冲的内容最终被写入正确的位置。
就上下文而言,GNU 文档对fopen 和更新模式保持相同的要求。与 C 和 POSIX 一样,fsetpos 没有说明输出缓冲区,但我的测试表明我的版本确实刷新了缓冲区。但是,fseek 可能会刷新缓冲区或记住足够的信息以确保最终正确写入其内容。
TL;DR: C 或 POSIX 是否不允许 fsetpos 丢弃写入缓冲区?是否有执行此操作的实现?
编辑:目前还没有人提供可靠的证据表明任一标准都禁止 fsetpos 丢弃写入缓冲区。同样,没有人提到任何执行此操作的实现。但是,这在 C 标准(附件 J)的可移植性问题列表中没有提到,这表明这是一个疏忽,而不是一个模糊的可移植性问题。此外,正如 R.. 所提到的,没有禁止完全不相关的函数丢弃缓冲区。
【问题讨论】: