16

I'm just curious which conditions should be satisfied to flush stdout buffer automatically.

First of all I was confused that this pseudo code doesn't print output every iteration:

while (1) {
    printf("Any text");
    sleep(1);
}

But if I add newline character it will.

After few experiments i found that on my machine stdout buffer is flushed:

  1. When I put to stdout 1025 characters or more;
  2. When I read stdin;
  3. When I put newline character to stdout;

The first condition is totally clear - when the buffer is full it should be flushed. The second one is also reasonable. But why newline character causes flushing? What are the others implicit conditions for this?

Andrii Zymohliad
  • 1,237
  • 1
  • 11
  • 17
  • I was recently informed (by @chux) that the third condition is not in the C standard, but is implementation defined, as are the first two. – Weather Vane Sep 16 '16 at 16:35
  • You might take a look at [http://stackoverflow.com/questions/13932932/why-does-stdout-need-explicit-flushing-when-redirected-to-file#13933741](http://stackoverflow.com/questions/13932932/why-does-stdout-need-explicit-flushing-when-redirected-to-file#13933741) – owacoder Sep 16 '16 at 16:35
  • 1
    @WeatherVane: I think you misunderstood. The behavior *is required* by C for line-buffered output streams, but stdout need not be line-buffered unless it is an interactive device. – R.. GitHub STOP HELPING ICE Sep 16 '16 at 16:36
  • @R.. that actual comment from chux was "Is `'\n'` *specified* to flush the output? `fflush(stdout);` seems more portable and certain...." so I was not so much informed, as questioned. – Weather Vane Sep 16 '16 at 16:40
  • @R.. Disagree with "The behavior is required by C" §7.21.3 says support for these characteristics is implementation-defined. More in [this answer](http://stackoverflow.com/a/39536803/2410359) – chux - Reinstate Monica Sep 16 '16 at 17:11

5 Answers5

18

Rules of automatic flushing stdout buffer is implementation-defined (ID). It is ID when the stream is unbuffered, fully buffered, or line buffered.

When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block.

When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled.

When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment.

Support for these characteristics is implementation-defined, ... C11dr §7.21.3 3


I'm just curious which conditions should be satisfied to flush stdout buffer automatically.

If code wants to insure output is certainly flushed, use fflush(). Other conditions that may automatically flush the stream are implementation defined.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
5
  • A output stream which is line-buffered shall be flushed whenever a newline is output.

  • An implementation may (but is not required to) flush all line-buffered output streams whenever a read is attempted from any line-buffered input stream.

  • Implementations are not allowed to make streams fully-buffered by default unless it can be determined that they are not associated with an "interactive device". So when stdin/stdout are terminals they can't be fully-buffered, only line-buffered (or unbuffered).

If you only need flushing when the output is to a terminal, it suffices to assume that writing a newline results in flushing. Otherwise you should explicitly call fflush wherever you need flushing.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Thank you. This clarifies a lot. – Andrii Zymohliad Sep 16 '16 at 17:14
  • Did not find the requirement for "Implementations are not allowed to make streams fully-buffered by default". Any cite? – chux - Reinstate Monica Feb 05 '20 at 02:17
  • 2
    @chux: 7.21.3 Files ¶7: "the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device." and 7.21.5.3 The fopen function ¶8: " When opened, a stream is fully buffered if and only if it can be determined not to refer to an interactive device." – R.. GitHub STOP HELPING ICE Feb 05 '20 at 03:13
  • Re: point 2, APUE says something similar: "Whenever input is requested through the standard I/O library from either (a) an unbuffered stream or (b) a line-buffered stream (that requires data to be requested from the kernel), all line-buffered output streams are flushed" (p.145-146). Is the idea that if you are moving on to processing the next line you should flush out any output generated from processing the current one? – Kvass Dec 17 '20 at 02:36
  • @Kvass: The idea is that some implementations do this to accommodate an idiom of printing a prompt string without a final newline then performing an input operation, without the program first flushing the output explicitly. However, this behavior is harmful and should be considered deprecated because it necessarily creates deadlocks in a multithreaded setting and (at least without complex bookkeeping) has O(n) time cost where n is number of open streams. – R.. GitHub STOP HELPING ICE Dec 17 '20 at 02:55
5

See the man page for setbuf(3). By default, stdout is set to line buffering mode.

printf() and its variants work with buffered output, and delegate to write(). So this buffering is controlled by the C library implementation of printf, with the buffer and buffer settings located in the FILE structure.

It's also worth noting the difference between section 3 and section 2 of the unix man pages. Section 2 is made up of function calls that directly talk to the operating system and do things that it would otherwise be impossible to do from a pure user program. Section 3 is made up of function calls that a user could reproduce on their own, which often delegate to section 2 calls. Section 2 functions contain the low-level "magic" that allow C programs to interact with the outside world and perform I/O. Section 3 functions can provide a more convenient interface to the section 2 functions.

printf, scanf, getchar, fputs, and other FILE * functions all are section 3 functions that delegate to write() and read(), which are section 2 functions. read() and write() do not buffer. printf() interacts with the buffer in the FILE structure, and occasionally decides to send the contents of that buffer out through write().

NovaDenizen
  • 5,089
  • 14
  • 28
  • 1
    Thank you. That's really usefull. I didn't know about those different types of buffers. And this man page explains everything. – Andrii Zymohliad Sep 16 '16 at 16:50
  • I wrote a short answer then edited in more detail, in case you missed it. – NovaDenizen Sep 16 '16 at 16:55
  • Oh yeah, I saw it only after your comment:) But anyway, that link is the most useful information about this for me. I knew about the difference between those man sections, but maybe it would be useful for someone else. Thanks. – Andrii Zymohliad Sep 16 '16 at 17:07
3

There are many circumstances when buffered output on a stream is flushed automatically:

  1. When you try to do output and the output buffer is full.
  2. When the stream is closed.
  3. When the program terminates by calling exit.
  4. When a newline is written, if the stream is line buffered.
  5. Whenever an input operation on any stream actually reads data from its file.

stdout is line buffered by default.

If you want to flush the buffered output at another time,You can call fflush.

Raman
  • 2,735
  • 1
  • 26
  • 46
  • 2
    `stdout` is only line-buffered if connected to a terminal. If the program is run with stdout redirected to a pipe or file, it will be full-buffered on normal Unix systems. So it depends what you mean by "default". (Apparently some IDEs use something other than a pseudo-terminal for running the prog being debugged, breaking interactive programs that assume line-buffered stdout: [Scanf executed before printf in Eclipse](https://stackoverflow.com/q/61503049) / [printf output always before scanf, who can give a solution?](https://stackoverflow.com/q/70709550)) – Peter Cordes Jan 15 '22 at 02:57
2

Online C2011 standard

7.21.3 Files
...
3     When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.
...
7     At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

So, a line buffered stream will flush on a newline. On most systems I have experience with, stdout is line buffered in an interactive session.

John Bode
  • 119,563
  • 19
  • 122
  • 198