Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the rules of automatic stdout buffer flushing in C?

Tags:

c

buffer

stdio

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?

like image 355
Andrii Zymohliad Avatar asked Sep 16 '16 16:09

Andrii Zymohliad


People also ask

What does Flushing buffer mean in C?

The buffer flush is used to transfer of computer data from one temporary storage area to computers permanent memory. If we change anything in some file, the changes we see on the screen are stored temporarily in a buffer. In C++, we can explicitly have flushed to force the buffer to be written.

What is flushing the output buffer?

Flushing output on a buffered stream means transmitting all accumulated characters to the file. There are many circumstances when buffered output on a stream is flushed automatically: When you try to do output and the output buffer is full. When the stream is closed.

When should you flush stdout?

So, what it basically comes down to is pretty simple: when you read from stdin , if anything has been written to stdout , but not flushed yet, it'll be flushed automatically before the system waits for input from stdin (unless you've done something like redirecting one or both to a file).

Is stdout buffered in C?

In C, file output is block buffered. Output to stdout is line buffered. The stderr device is unbuffered.


5 Answers

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.

like image 184
BitFlip Avatar answered Oct 07 '22 11:10

BitFlip


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.

like image 42
chux - Reinstate Monica Avatar answered Oct 07 '22 10:10

chux - Reinstate Monica


  • 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.

like image 36
R.. GitHub STOP HELPING ICE Avatar answered Oct 07 '22 09:10

R.. GitHub STOP HELPING ICE


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().

like image 32
NovaDenizen Avatar answered Oct 07 '22 10:10

NovaDenizen


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.

like image 22
John Bode Avatar answered Oct 07 '22 11:10

John Bode