【问题标题】:Is `clog` buffered?`clog` 被缓冲了吗?
【发布时间】:2021-04-20 12:00:45
【问题描述】:

我在很多地方读到clogcerr 相同,除了clog 被缓冲而cerr 不是。但是我在我的计算机上看不到这种行为(Ubuntu 20.04,clang 9)。这是我使用的代码:

clog << "AA";
this_thread::sleep_for(chrono::seconds(3));
clog << endl;
clog << "BB" << endl;

当我使用cout 而不是clog 时,前3 秒内我看不到任何东西;然后我立即看到 AA 和 BB。

当我使用cerr 而不是clog 时,我立即看到AA,然后在3 秒后看到BB。

当我使用clog 时,我看到的和cerr 完全一样 --- 立即 AA,然后在 3 秒后我看到 BB。

如果clog 被缓冲,它的行为不应该像cout吗?

这是我的编译器中的错误吗?

【问题讨论】:

  • “我在很多地方都看过……” - 那些地方可能不太靠谱。
  • 是的,std::clog is buffered 但是这个缓冲区的行为是由实现定义的。

标签: c++ buffer iostream


【解决方案1】:

这不是一个错误,clog 不应该被缓冲,事实上该标准并未以任何方式将 clogcout 关联起来,也没有声明 clog 应该被缓冲。

它确实声明cerrclog 都与stderr 相关联,所以如果行为上有一些相似之处,它应该在clogcerr 之间,这似乎是什么你正在经历。

由于stderr 被定义为无缓冲,逻辑上clog 也无缓冲,但由于未指定此行为,因此不能保证始终如此。

coutstdout 相关联,其缓冲设置取决于环境。通常,对于 UNIX 系统,它是行缓冲的。

29.4.3 窄流对象 [narrow.stream.objects]

ostream cout;

3 - 对象cout 控制输出到与stdout 对象关联的流缓冲区,在&lt;cstdio&gt;(29.12.1) 中声明。

ostream cerr;

4 - 对象 cerr 控制输出到与对象 stderr 关联的流缓冲区,在 &lt;cstdio&gt;(29.12.1) 中声明。

[...]

ostream 堵塞;

6 - clog 对象控制输出到与stderr 对象关联的流缓冲区,在&lt;cstdio&gt;(29.12.1) 中声明。

【讨论】:

  • 这个答案错过了 IMO 的重点。 cerr 保证是无缓冲的(它在由点指定的省略中),而 clog 未指定它。所以它可能是。假设“clog 应该被缓冲”是谬误。
  • 他们显然委托给stderr,因此在某种程度上依赖于它的行为,但没有什么能迫使他们成为愚蠢的委托人。他们被允许在他们指向的流上实现缓冲。
  • @StoryTeller-UnslanderMonica 知道了。
  • @StoryTeller-UnslanderMonica TBF 即使在 cppreference 中,描述也有点误导The global objects std::clog and std::wclog control output to a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C output stream stderr, but, unlike std::cerr/std::wcerr, these streams are not automatically flushed and cout is not automatically tie()'d with these streams.
猜你喜欢
  • 1970-01-01
  • 2011-11-17
  • 2017-06-28
  • 1970-01-01
  • 2014-06-01
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多