【问题标题】:Sanity check: Does returning !EOF from streambuf-derived class' overflow function make sense?完整性检查:从 streambuf 派生类的溢出函数返回 !EOF 是否有意义?
【发布时间】:2023-01-29 00:25:10
【问题描述】:

关于重写的 std::streambuf::overflow 函数应该如何简单地获取写入流的每个字符,我发现的有用信息很少。所以我向 ChatGPT 寻求一些建议。它不断回到这个概念:

int overflow(int c)
{
    if (c == EOF)
    {
        // Flush the buffer here
        return !EOF;
    }
    // Put c in the buffer here
    if (c == '\n')
    {
        // Flush the buffer here
    }
    return c;
}

当 c 是 EOF 时,它返回 !EOF 真是太奇怪了。
The docs不要详细说明“成功”是什么意思。
This page 表示当以 EOF 作为参数调用时(或发出“失败”信号时),它应该返回 EOF(而不是 !EOF)。

所以:我怀疑在这里返回 !EOF 是错误的并且我应该返回 EOF 是否正确?
如果您能告诉我 ChatGPT 从哪里得到这个想法,请使用 Cookie 点数。我在互联网上的其他任何地方都找不到return !EOF;。

【问题讨论】:

  • @Someprogrammerdude 是否用 EOF 调用它作为被认为“成功”的参数?此外,Traits::eof() 是一个常量值,所以我不确定“如果流已到达文件末尾,Treats::eof() 返回 true”是什么意思。 !EOF 变为 false,变为 0。
  • 这可能与成功时需要返回不同于 Traits::eof() 的值的函数有关。显然代码认为 EOF 是一个成功的案例。
  • 话虽如此,ChatGPT 对于实际和事实信息来说确实不可靠。它可以生成看起来不错且真实的文本和代码,但仔细观察往往并非如此。这里禁止使用 ChatGPT 生成的答案是有原因的。我不会相信它生成的任何代码。
  • !EOF 没有任何意义(这只是拼写常量 false 的一种有趣方式)。
  • “我问 ChatGPT” 你得到了你付出的代价。

标签: c++ c++17 streambuf


【解决方案1】:

这是 C++ 标准对返回值的规定:

[streambuf.virt.put]

int_type overflow(int_type c = traits::eof());

6个 退货:traits::eof() 或在函数失败时抛出异常。
否则,返回 traits::eof() 以外的一些值以指示成功。(304)

(脚注 304)通常,overflow 返回 c 表示成功,除非 traits::eq_int_type(c, traits::eof()) 返回 true,在这种情况下它返回 traits::not_eof(c)。

因此,具体的返回值并不重要,重要的是是否为traits::eof()。您可能想要遵循一个(非规范的)约定。

回复:“成功”是什么意思:

[streambuf.virt.put]/5 要求:此虚函数的每个重写定义都应遵守以下约束:
...

  1. 设r 为待处理序列中未消耗的字符数。如果r 非零,则应设置pbase() 和pptr(),以便:pptr() - pbase() == r 和pbase() 开始的r 字符是关联的输出流。如果 r 为零(待处理序列的所有字符都已被消耗),则将 pbase() 设置为 nullptr,或者将 pbase() 和 pptr() 都设置为相同的非空值。
  2. 如果将某些字符附加到关联的输出流失败,或者无法根据上述规则建立pbase()和pptr(),则该函数可能会失败。

因此,如果函数无法实际写入底层介质,或者无法恢复不变量,则该函数将失败。如果它管理两者,它就会成功。

【讨论】:

    猜你喜欢
    • 2021-04-13
    • 2021-12-02
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2021-08-10
    • 2018-06-22
    相关资源
    最近更新 更多